ตัวแปร $ _SERVER ใดที่ปลอดภัย


97

ตัวแปรใด ๆ ที่ผู้ใช้สามารถควบคุมได้ผู้โจมตีก็สามารถควบคุมได้เช่นกันดังนั้นจึงเป็นที่มาของการโจมตี สิ่งนี้เรียกว่าตัวแปร "แปดเปื้อน" และไม่ปลอดภัย

เมื่อใช้$_SERVERสามารถควบคุมตัวแปรหลายตัวได้ PHP_SELF, HTTP_USER_AGENT, HTTP_X_FORWARDED_FOR, HTTP_ACCEPT_LANGUAGEและอื่น ๆ อีกมากมายเป็นส่วนหนึ่งของส่วนหัวของการร้องขอ HTTP ที่ส่งมาจากลูกค้า

มีใครรู้จัก "รายการที่ปลอดภัย" หรือรายการ$_SERVERตัวแปรที่ไม่มีการเคลือบหรือไม่


8
ขึ้นอยู่กับว่าคุณกำหนดคำว่า "ปลอดภัย" ไว้อย่างไร ค่าทั้งหมดปลอดภัยตามที่เป็นจริงขึ้นอยู่กับสิ่งที่คุณใช้เท่านั้น
หลอกลวง

6
ผมคิดว่าในบริบทนี้โกงไม่ว่าจะเป็น "ซึ่งตัวแปรเซิร์ฟเวอร์ไม่สามารถปลอมแปลงได้โดยผู้ใช้" REMOTE_ADDRเช่น
vcsjones

6
สิ่งที่นำหน้าHTTP_คือส่วนหัวของคำขอและสามารถตั้งค่าได้โดยเบราว์เซอร์หรือพร็อกซีระหว่างกัน ฉันจะถือว่าสิ่งเหล่านี้เป็นการป้อนข้อมูลของผู้ใช้รายอื่น
ข้อมูล

3
@ bob-the-destroyer REMOTE_ADDR ถูกดึงโดยตรงจากซ็อกเก็ต TCP ของ apache ค่านี้ไม่สามารถปลอมแปลงทางอินเทอร์เน็ตได้เนื่องจากการจับมือกันสามทาง
rook

2
@Rook: จุดดี. ผมคิดว่าที่มีการกล่าวถึง "โต้" ผมได้มากขึ้นพิงต่อการกระทำที่เก่าปลอมแปลง IP REMOTE_ADDRตัวเองมากกว่าการจัดเรียงของแกล้งค่าจริงใด และนั่นจะไม่อยู่ในขอบเขตของคำถามนี้ ดีที่ได้รับข้อมูลเชิงลึกเกี่ยวกับวิธีการตั้งค่านี้ขอบคุณมาก
bob-the-destroyer

คำตอบ:


147

ไม่มีค่าที่เรียกว่า "ปลอดภัย" หรือ "ไม่ปลอดภัย" เช่นนี้ มีเพียงค่าที่เซิร์ฟเวอร์ควบคุมและค่าที่ผู้ใช้ควบคุมและคุณจำเป็นต้องทราบว่าค่านั้นมาจากไหนและด้วยเหตุนี้จึงสามารถเชื่อถือได้สำหรับวัตถุประสงค์บางอย่างหรือไม่ $_SERVER['HTTP_FOOBAR']ตัวอย่างเช่นปลอดภัยอย่างยิ่งที่จะจัดเก็บในฐานข้อมูล แต่แน่นอนว่าฉันจะไม่evalทำเช่นนั้น

ดังนั้นเรามาแบ่งค่าเหล่านี้ออกเป็นสามประเภท:

ควบคุมเซิร์ฟเวอร์

ตัวแปรเหล่านี้ถูกกำหนดโดยสภาพแวดล้อมของเซิร์ฟเวอร์และขึ้นอยู่กับการกำหนดค่าเซิร์ฟเวอร์ทั้งหมด

  • 'GATEWAY_INTERFACE'
  • 'SERVER_ADDR'
  • 'SERVER_SOFTWARE'
  • 'DOCUMENT_ROOT'
  • 'SERVER_ADMIN'
  • 'SERVER_SIGNATURE'

ควบคุมเซิร์ฟเวอร์บางส่วน

ตัวแปรเหล่านี้ขึ้นอยู่กับคำขอเฉพาะที่ไคลเอ็นต์ส่ง แต่สามารถรับค่าที่ถูกต้องได้ในจำนวน จำกัด เนื่องจากเว็บเซิร์ฟเวอร์ควรปฏิเสธค่าที่ไม่ถูกต้องทั้งหมดและไม่ทำให้การเรียกใช้สคริปต์เริ่มต้นด้วย ดังนั้นจึงถือได้ว่าเชื่อถือได้

  • 'HTTPS'
  • 'REQUEST_TIME'
  • 'REMOTE_ADDR' *
  • 'REMOTE_HOST' *
  • 'REMOTE_PORT' *
  • 'SERVER_PROTOCOL'
  • 'HTTP_HOST'
  • 'SERVER_NAME'
  • 'SCRIPT_FILENAME'
  • 'SERVER_PORT'
  • 'SCRIPT_NAME'

* REMOTE_ค่านี้รับประกันว่าเป็นที่อยู่ที่ถูกต้องของไคลเอนต์ซึ่งตรวจสอบโดยการจับมือ TCP / IP นี่คือที่อยู่ที่จะส่งคำตอบไปที่REMOTE_HOSTต้องอาศัยการค้นหา DNS แบบย้อนกลับและอาจถูกปลอมแปลงโดยการโจมตี DNS กับเซิร์ฟเวอร์ของคุณ (ซึ่งในกรณีนี้คุณจะมีปัญหาใหญ่กว่า) ค่านี้อาจเป็นพร็อกซีซึ่งเป็นความจริงง่ายๆของโปรโตคอล TCP / IP และคุณไม่สามารถทำอะไรได้เลย

†หากเว็บเซิร์ฟเวอร์ของคุณตอบสนองต่อคำขอใด ๆโดยไม่คำนึงถึงHOSTส่วนหัวสิ่งนี้ควรได้รับการพิจารณาว่าไม่ปลอดภัยเช่นกัน ดู$ _SERVER [“ HTTP_HOST”] ปลอดภัยแค่ไหน? .
โปรดดูที่http://shiflett.org/blog/2006/mar/server-name-versus-http-host http://shiflett.org/blog/2006/mar/server-name-versus-http-host

‡ดูhttps://bugs.php.net/bug.php?id=64457 , http://httpd.apache.org/docs/current/mod/core.html#usecanonicalphysicalport , http://httpd.apache org / docs / 2.4 / mod / core.html # comment_999

ค่าที่ผู้ใช้ควบคุมโดยพลการทั้งหมด

ค่าเหล่านี้ไม่ได้รับการตรวจสอบเลยและไม่ขึ้นอยู่กับการกำหนดค่าเซิร์ฟเวอร์ใด ๆ ค่าเหล่านี้เป็นข้อมูลที่ลูกค้าส่งมาโดยพลการ

  • 'argv', 'argc' (ใช้ได้กับการเรียก CLI เท่านั้นโดยปกติแล้วจะไม่เป็นปัญหาสำหรับเว็บเซิร์ฟเวอร์)
  • 'REQUEST_METHOD' §
  • 'QUERY_STRING'
  • 'HTTP_ACCEPT'
  • 'HTTP_ACCEPT_CHARSET'
  • 'HTTP_ACCEPT_ENCODING'
  • 'HTTP_ACCEPT_LANGUAGE'
  • 'HTTP_CONNECTION'
  • 'HTTP_REFERER'
  • 'HTTP_USER_AGENT'
  • 'AUTH_TYPE'
  • 'PHP_AUTH_DIGEST'
  • 'PHP_AUTH_USER'
  • 'PHP_AUTH_PW'
  • 'PATH_INFO'
  • 'ORIG_PATH_INFO'
  • 'REQUEST_URI' (อาจมีข้อมูลที่ปนเปื้อน)
  • 'PHP_SELF' (อาจมีข้อมูลที่ปนเปื้อน)
  • 'PATH_TRANSLATED'
  • 'HTTP_'ค่าอื่น ๆ

§อาจได้รับการพิจารณาว่าเชื่อถือได้ตราบเท่าที่เว็บเซิร์ฟเวอร์อนุญาตเฉพาะวิธีการร้องขอบางวิธีเท่านั้น

‖อาจถือว่าเชื่อถือได้หากการตรวจสอบถูกจัดการโดยเว็บเซิร์ฟเวอร์ทั้งหมด

superglobal $_SERVERยังรวมถึงตัวแปรสภาพแวดล้อมต่างๆ สิ่งเหล่านี้ "ปลอดภัย" หรือไม่ขึ้นอยู่กับวิธีการกำหนด (และที่ใด) สามารถมีตั้งแต่เซิร์ฟเวอร์ที่ควบคุมอย่างสมบูรณ์ไปจนถึงควบคุมโดยผู้ใช้ทั้งหมด


3
@Rook แต่อย่างที่บอกมันขึ้นอยู่กับว่าคุณใช้มันอย่างไร ค่าเพียงแค่ตัวเองจะไม่ปลอดภัยหรือไม่ปลอดภัยก็ขึ้นอยู่กับสิ่งที่คุณใช้พวกเขาสำหรับ แม้แต่ข้อมูลที่ส่งมาจากผู้ใช้ที่ชั่วร้ายก็ยังปลอดภัยอย่างสมบูรณ์ตราบเท่าที่คุณไม่ได้ทำอะไรกับข้อมูลที่อาจส่งผลต่อความปลอดภัยของคุณ
หลอกลวง

2
@Rook: ความคิดของคุณเกี่ยวกับ "ปลอดภัย" ทำให้คำถามนี้ดูเป็นไปโดยพลการโดยเฉพาะอย่างยิ่งเมื่อมันเชื่อมโยงกับส่วนขยายที่คลุมเครือหรือ PHP เวอร์ชันที่กำหนดเอง ในขณะที่คุณพูดว่า "ไม่ควรมีแนวทาง" ยิงจากสะโพก "แต่คำตอบใด ๆ ดูเหมือนว่าจะต้องมีความคุ้นเคยขั้นต่ำกับซอร์สโค้ด PHP เพื่อดูว่าค่าเหล่านี้ถูกกำหนดไว้อย่างไร การส่งอีเมลถึงนักพัฒนา PHP จะไม่ใช่วิธีที่ดีกว่าในการค้นหาคำตอบหรือไม่?
bob-the-destroyer

2
@ Rook: การสื่อสารผิดพลาด ตามที่ผู้หลอกลวงบอกเป็นนัย ๆ ว่า "ปลอดภัยสำหรับวัตถุประสงค์อะไร" ตามที่ฉันบอกเป็นนัยว่าจุดประสงค์ของคุณไม่เป็นที่รู้จักและนอกจากนี้ยังมี$_SERVERค่าอื่น ๆ ที่ไม่มีเอกสารอีกหลายค่าขึ้นอยู่กับวิธีการให้บริการไฟล์ ในความคิดของฉันเอกสารไม่ได้ชี้แจงแหล่งที่มาที่แท้จริง ไม่งั้นฉันเชื่อว่าคุณคงไม่ถามคำถามนี้ ดีใจที่คุณมีรายชื่อที่สามารถใช้ได้ แต่ฉันยังคงแนะนำให้ส่งรายงานข้อบกพร่อง (เมื่อไซต์จุดบกพร่องของพวกเขาได้รับการแก้ไขแล้ว) ส่งอีเมลถึงผู้ดูแลรักษาเอกสารหรืออัปเดตเอกสารด้วยตัวคุณเอง (หากคุณเป็นสมาชิกของลิงก์) จะเป็นประโยชน์ต่อชุมชนเมื่อทราบข้อมูลนี้
bob-the-destroyer

3
SERVER_NAMEไม่จำเป็นต้องควบคุมโดยเซิร์ฟเวอร์ ขึ้นอยู่กับเกตเวย์และการตั้งค่าอาจซ้ำกันHTTP_HOSTและด้วยเหตุนี้จึงมีข้อแม้เดียวกัน
bobince

1
@deceze @Rook SERVER_PORTต้องการไม้กางเขนเล็กน้อยหรือไม่? bugs.php.net/bug.php?id=64457
Dejan Marjanović

12

ใน PHP ทุก$_SERVERตัวแปรที่ขึ้นต้นด้วยHTTP_จะได้รับอิทธิพลจากผู้ใช้ ตัวอย่างเช่นตัวแปร$_SERVER['HTTP_REINERS']สามารถปนเปื้อนได้โดยการตั้งค่าส่วนหัว HTTP REINERSเป็นค่าที่กำหนดเองในคำขอ HTTP


re "ตามอำเภอใจ"; ไม่ใช่ทั้งหมดโดยพลการเนื่องจากเป็นไปตามรูปแบบ ตัวอย่างเช่น$_SERVER['HTTP_REINERS'] ไม่สามารถมีอักขระขึ้นบรรทัดใหม่ภายใต้ sapis ส่วนใหญ่
Pacerier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.