เกิดอะไรขึ้นกับการใช้ $ _REQUEST []


116

ฉันเคยเห็นโพสต์จำนวนมากในที่นี่บอกว่าอย่าใช้$_REQUESTตัวแปร ฉันมักจะไม่ทำ แต่บางครั้งก็สะดวก มันผิดอะไร?


2
ดูคำถามและคำตอบที่เกี่ยวข้อง: stackoverflow.com/questions/1149118/…
Gordon

2
ตั้งแต่ PHP 5.3 php.ini เริ่มต้นกล่าวว่าจะได้รับและข้อมูล POST $_REQUESTจะใส่ลงใน ดูphp.net/request_orderฉันเพิ่งสะดุดกับตัวแบ่งความเข้ากันได้แบบย้อนกลับนี้เมื่อคาดว่าจะมีข้อมูลคุกกี้เข้ามา$_REQUESTและสงสัยว่าทำไมมันถึงไม่ทำงาน! ดังนั้นเหตุผลที่ใหญ่ที่สุดในการหลีกเลี่ยงการใช้ $ _REQUEST ก็คือตอนนี้สคริปต์ของคุณไม่สามารถตั้งค่าrequest_orderเองได้PHP_INI_PERDIRดังนั้นการเปลี่ยนแปลง php.ini สามารถทำลายสมมติฐานที่สคริปต์ของคุณสร้างขึ้นได้อย่างง่ายดาย ดีกว่าที่จะใส่สมมติฐานเหล่านั้นลงในสคริปต์ของคุณโดยตรง
Darren Cook

คำตอบ:


184

ไม่มีอะไรผิดปกติกับการรับข้อมูลจากทั้งสองอย่าง$_GETและ$_POSTรวมกัน ในความเป็นจริงนั่นคือสิ่งที่คุณอยากทำเกือบตลอดเวลา:

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

  • สำหรับคำขอที่มีผลจริงคุณต้องตรวจสอบว่าส่งโดยวิธี POST แต่วิธีที่จะทำคือตรวจสอบ$_SERVER['REQUEST_METHOD']อย่างชัดเจนไม่ต้องพึ่งพา$_POSTการว่างเปล่าสำหรับ GET และอย่างไรก็ตามหากเป็นวิธีนี้POSTคุณอาจต้องการนำพารามิเตอร์การสืบค้นบางส่วนออกจาก URL

ไม่ปัญหา$_REQUESTคือไม่เกี่ยวข้องกับการรวมพารามิเตอร์ GET และ POST โดยค่าเริ่มต้นจะรวม$_COOKIEไว้ด้วย และคุกกี้ไม่เหมือนกับพารามิเตอร์การส่งแบบฟอร์มเลยจริงๆคุณแทบไม่อยากจะถือว่ามันเป็นสิ่งเดียวกัน

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

คุณสามารถเปลี่ยนพฤติกรรมนี้เป็นคำสั่งGP(ไม่C) ที่สมเหตุสมผลมากขึ้นด้วยการกำหนดค่าrequest_orderใน PHP 5.3 ในกรณีที่เป็นไปไม่ได้ฉันจะหลีกเลี่ยงเป็นการส่วนตัว$_REQUESTและถ้าฉันต้องการอาร์เรย์ GET + POST รวมกันให้สร้างด้วยตนเอง


2
สถานการณ์เหล่านี้ (ข้อมูลยาวเกินไปที่จะส่งผ่าน GET) เป็นข้อยกเว้นไม่ใช่กฎ
Ben James

1
คำตอบที่ดี ฉันยังสังเกตเห็นว่าด้วยเฟรมเวิร์กเช่น Zend Framework GET และพารามิเตอร์ POST จะรวมกันเป็นวัตถุคำขอ 1 รายการ มันไม่เคยทำให้ฉันประทับใจจนกว่าฉันจะอ่านโพสต์ของคุณ
Jay Sidri

ตามค่าเริ่มต้นการกำหนดค่าrequest_orderจะตั้งค่าเป็น "GP" ในphp.iniตั้งแต่ PHP 5.4+ ดังนั้นฉันจะบอกว่าไปเลย ... แต่เช่นเคยโปรดดำเนินการด้วยความระมัดระวัง
bcmoney

ถ้า $ _POST เป็นa="foo"และ $ _COOKIE a="bar"จะมีการแทนที่ / ความขัดแย้งที่นี่หรือไม่?
สนิม

75

ฉันได้ดูโพสต์กลุ่มข่าวในPHP Internalsและพบการสนทนาที่น่าสนใจเกี่ยวกับหัวข้อนี้ หัวข้อแรกคือเกี่ยวกับสิ่งอื่น แต่คำพูดโดย Stefan Esser เป็น (ถ้าไม่) ผู้เชี่ยวชาญด้านความปลอดภัยในโลก PHP เปิดการสนทนาที่มีต่อผลกระทบการรักษาความปลอดภัยของการใช้ $ _REQUEST สำหรับการโพสต์ไม่กี่

อ้างถึงStefan Esser ใน PHP Internals

$ _REQUEST เป็นจุดอ่อนด้านการออกแบบที่ใหญ่ที่สุดอย่างหนึ่งใน PHP ทุกแอปพลิเคชันที่ใช้ $ _REQUEST มักเสี่ยงต่อปัญหาการปลอมแปลงคำขอข้ามไซต์ที่ล่าช้า (โดยทั่วไปหมายความว่าหากมีคุกกี้ชื่อ (อายุ) อยู่มันจะเขียนทับเนื้อหา GET / POST เสมอดังนั้นการร้องขอที่ไม่ต้องการจะถูกดำเนินการ)

และในภายหลังตอบกลับเธรดเดียวกัน

ไม่เกี่ยวกับการที่ใครบางคนสามารถปลอม GET, POST; ตัวแปร COOKIE เป็นเรื่องเกี่ยวกับข้อเท็จจริงที่ว่าคุกกี้จะเขียนทับข้อมูล GET และ POST ใน REQUEST

ดังนั้นฉันสามารถทำให้เบราว์เซอร์ของคุณติดเชื้อด้วยคุกกี้ที่ระบุว่าเช่น action = logout และตั้งแต่วันนั้นเป็นต้นมาคุณไม่สามารถใช้แอปพลิเคชันได้อีกต่อไปเนื่องจาก REQUEST [action] จะถูกล็อกเอาต์ตลอดไป (จนกว่าคุณจะลบคุกกี้ด้วยตนเอง)

และการทำให้คุณติดคุกกี้นั้นง่ายมาก
ก) ฉันสามารถใช้ XSS vuln ในแอปพลิเคชันใดก็ได้บนโดเมนย่อย
b) เคยลองตั้งค่าคุกกี้สำหรับ * .co.uk หรือ * .co.kr เมื่อคุณเป็นเจ้าของ โดเมนเดียวมีไหม
c) ข้ามโดเมนอื่น ๆ ไม่ว่าจะด้วยวิธีใดก็ตาม ...

และถ้าคุณเชื่อว่านี่ไม่ใช่ปัญหาฉันสามารถบอกคุณได้ว่ามีความเป็นไปได้ง่ายๆในการตั้งค่าคุกกี้ * .co.kr ที่ส่งผลให้ PHP หลายเวอร์ชันกลับมาเป็นไวท์เพจ ลองนึกภาพ: เพียงคุกกี้เดียวเพื่อฆ่าหน้า PHP ทั้งหมดใน * .co.kr

และด้วยการตั้งรหัสเซสชันที่ผิดกฎหมายในคุกกี้ที่ถูกต้องสำหรับ * .co.kr ในตัวแปรที่เรียกว่า + PHPSESSID = ผิดกฎหมายคุณยังคงสามารถ DOS ทุกแอปพลิเคชัน PHP ในเกาหลีโดยใช้เซสชัน PHP ...

การสนทนายังคงดำเนินต่อไปอีกสองสามโพสต์และน่าสนใจที่จะอ่าน


อย่างที่คุณเห็นปัญหาหลักของ $ _REQUEST ไม่มากนักเนื่องจากมีข้อมูลจาก $ _GET และ $ _POST แต่ยังมาจาก $ _COOKIE บางคนอื่น ๆ ในรายการแนะนำเปลี่ยนแปลงลำดับที่ $ _REQUEST เต็มไปเช่นกรอกด้วย $ _COOKIE แรก แต่นี้อาจนำไปสู่ปัญหามากมายมีศักยภาพอื่น ๆ เช่นกับการจัดการเซสชัน

คุณสามารถละ $ _COOKIES จาก $ _REQUEST global ได้อย่างสมบูรณ์เพื่อที่จะไม่ถูกเขียนทับโดยอาร์เรย์อื่น ๆ (อันที่จริงคุณสามารถ จำกัด การรวมกันของเนื้อหามาตรฐานเช่นคู่มือ PHP ในการตั้งค่าvariable_order iniบอกพวกเรา:

variable_order ตั้งค่าลำดับของการแยกวิเคราะห์ตัวแปร EGPCS (Environment, Get, Post, Cookie และ Server) ตัวอย่างเช่นหากกำหนดค่า variable_order เป็น "SP" PHP จะสร้าง superglobals $ _SERVER และ $ _POST แต่ไม่สร้าง $ _ENV, $ _GET และ $ _COOKIE การตั้งค่าเป็น "" หมายความว่าจะไม่มีการตั้งค่า superglobals

แต่อีกครั้งคุณอาจพิจารณาที่จะไม่ใช้ $ _REQUEST โดยสิ้นเชิงเพียงเพราะใน PHP คุณสามารถเข้าถึง Environment, Get, Post, Cookie และ Server ในโลกของพวกเขาเองและมีเวกเตอร์การโจมตีน้อยกว่าหนึ่งตัว คุณยังคงต้องล้างข้อมูลนี้ แต่สิ่งหนึ่งที่ไม่ต้องกังวล


ตอนนี้คุณอาจสงสัยว่าทำไม $ _REQUEST ถึงมีอยู่และทำไมมันไม่ถูกลบออก สิ่งนี้ถูกถามใน PHP Internals เช่นกัน อ้างถึง Rasmus Lerdorf เกี่ยวกับเหตุใด $ _REQUEST จึงมีอยู่ บน PHP Internals

ยิ่งเราลบสิ่งเหล่านี้ออกไปมากเท่าไหร่ผู้คนก็จะยิ่งเปลี่ยนไปใช้ PHP เวอร์ชันใหม่เร็วขึ้นและปลอดภัยมากขึ้นเท่านั้น นั่นทำให้ทุกคนไม่สบายใจมากกว่าฟีเจอร์เดิมที่ "น่าเกลียด" เพียงเล็กน้อย หากมีเหตุผลทางเทคนิคประสิทธิภาพหรือความปลอดภัยที่เหมาะสมเราจำเป็นต้องพิจารณาอย่างหนัก ในกรณีนี้สิ่งที่เราควรพิจารณาไม่ใช่ว่าเราควรลบ $ _REQUEST หรือไม่ แต่เราควรลบข้อมูลคุกกี้ออกหรือไม่ การกำหนดค่าหลายอย่างทำเช่นนั้นแล้วรวมถึงของฉันเองทั้งหมดและมีเหตุผลด้านความปลอดภัยที่ถูกต้องที่ชัดเจนในการไม่รวมคุกกี้ใน $ _REQUEST คนส่วนใหญ่ใช้ $ _REQUEST เพื่อหมายถึง GET หรือ POST โดยไม่ทราบว่ามันอาจมีคุกกี้ด้วยและคนเลวเหล่านี้อาจใช้เทคนิคการฉีดคุกกี้และทำลายแอปพลิเคชันที่ไร้เดียงสาได้

ยังไงก็หวังว่าคงกระจ่างขึ้นบ้าง


1
+1 ดีที่ได้เห็นการสนทนาเกี่ยวกับเรื่องนี้ ... ฉันคิดว่าฉันจะบ้าตาย!
bobince

2
ฉันคิดว่าการสนทนานั้นมีการพูดคุยกันมากเกินไป ปัญหาที่แท้จริงคือความไม่ทราบของนักพัฒนาไม่ใช่การมีอยู่ของคุกกี้ใน $ _REQUEST ต่อ se ตัวอย่างเช่น PHPSESSID ที่แก้ไขแล้วจะถูกรีเซ็ตด้วยคุกกี้ต่อโดเมนด้วยรหัสการจัดการเซสชันร่วมสมัย และสำหรับบางแอปพลิเคชันอาจต้องการตัวแปรคำขอลบล้างคุกกี้ (เช่น sort_order = ASC แทนที่รูปแบบการค้นหา GET var) แม้ว่าการเขียนโค้ดในพฤติกรรมดังกล่าวจะสมเหตุสมผลกว่า
มาริโอ

1
โพสต์ที่ครอบคลุมมากนี่น่าจะเป็นคำตอบ อาจจะมีคนกลัวโพสต์ยาว ๆ ;)
Dzung Nguyen

น่าเศร้าที่ Rasmus แสดงความคิดเห็นเกี่ยวกับเรื่องนี้ในปี 2009 แต่ตอนนี้ $ _REQUEST ก็เหมือนเดิมในปี 2015
Kzqai

10

$_REQUESTหมายถึงคำขอทุกประเภท (GET, POST ฯลฯ .. ) บางครั้งสิ่งนี้มีประโยชน์ แต่โดยปกติแล้วการระบุวิธีการที่แน่นอนจะดีกว่า ($ _GET, $ _POST ฯลฯ )


19
คำตอบนี้อธิบายว่า $ _REQUEST คืออะไร แต่ไม่ตอบคำถาม
zombat

1
เขากำลังบอกว่ามันเป็นเพียงแนวทางปฏิบัติที่ดีกว่าที่จะรู้ว่าคำขอประเภทใดที่จะเข้ามาและตั้งรหัสให้กับคำขอนั้น ๆ
Polaris878

8

$_REQUEST โดยทั่วไปถือว่าเป็นอันตรายด้วยเหตุผลเดียวกับที่การแปลงข้อมูลแบบง่ายถึงปานกลาง - ซับซ้อนมักจะดำเนินการในโค้ดแอปพลิเคชันแทนที่จะประกาศใน SQL: โปรแกรมเมอร์บางคนดูด

ด้วยเหตุนี้หากมีแนวโน้มที่จะใช้$_REQUESTทุกที่ฉันสามารถทำอะไรก็ได้ผ่าน GET ที่ฉันทำได้ผ่าน POST ซึ่งหมายถึงการตั้งค่า<img>แท็กบนไซต์ (ที่เป็นอันตราย) ของฉันซึ่งทำให้ผู้ใช้ที่ลงชื่อเข้าใช้โมดูลอีคอมเมิร์ซของคุณซื้อผลิตภัณฑ์โดยไม่โต้ตอบหรือฉัน อาจทำให้พวกเขาคลิกลิงก์ที่จะส่งผลให้เกิดการกระทำที่เป็นอันตรายหรือการเปิดเผยข้อมูลที่ละเอียดอ่อน (อาจเป็นสำหรับฉัน)

อย่างไรก็ตามนี่เป็นเพราะมือใหม่หรืออย่างน้อยก็ไม่มีประสบการณ์โปรแกรมเมอร์ PHP ที่ทำผิดพลาดง่ายๆ ก่อนอื่นให้ทราบเมื่อข้อมูลประเภทใดเหมาะสม ตัวอย่างเช่นฉันมีบริการเว็บที่สามารถส่งคืนการตอบกลับใน URLEncoding, XML หรือ JSON แอปพลิเคชันตัดสินใจว่าจะจัดรูปแบบการตอบกลับอย่างไรโดยการตรวจสอบส่วนหัว HTTP_ACCEPT แต่สามารถบังคับให้เป็นหนึ่งเดียวโดยเฉพาะได้โดยการส่งformatพารามิเตอร์

เมื่อตรวจสอบเนื้อหาของพารามิเตอร์รูปแบบสามารถส่งผ่านสตริงการสืบค้นหรือข้อมูลภายหลังขึ้นอยู่กับปัจจัยหลายประการไม่ใช่อย่างน้อยที่สุดคือแอปพลิเคชันการโทรต้องการ "& format = json" ผสมกับคำขอหรือไม่ ในกรณี$_REQUESTนี้สะดวกมากเพราะช่วยให้ฉันไม่ต้องพิมพ์อะไรแบบนี้:

$format = isset($_POST['format']) ? $_POST['format'] 
    : (isset($_GET['format']) ? $_GET['format'] : null);

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

วิธีใช้$_REQUESTอย่างปลอดภัย


  1. รู้ข้อมูลของคุณ : คุณควรมีความคาดหวังว่าคุณจะได้รับข้อมูลประเภทใดดังนั้นจึงต้องล้างข้อมูลให้ถูกต้อง ข้อมูลสำหรับฐานข้อมูล? addslashes()หรือ*_escape_string(). ไปแสดงกลับมาให้ผู้ใช้? htmlentities()หรือhtmlspecialchars(). คาดหวังข้อมูลตัวเลข? is_numeric()หรือctype_digit(). ในความเป็นจริงfilter_input()และฟังก์ชันที่เกี่ยวข้องได้รับการออกแบบมาเพื่อทำอะไรนอกจากตรวจสอบและฆ่าเชื้อข้อมูล ใช้เครื่องมือเหล่านี้เสมอ
  2. ทำผู้ใช้จัดข้อมูล superglobals ไม่เข้าถึงโดยตรง สร้างนิสัยในการล้างข้อมูลของคุณทุกครั้งและย้ายข้อมูลของคุณเพื่อล้างตัวแปรแม้ว่าจะเป็นเพียงแค่$post_cleanก็ตาม หรือคุณสามารถทำความสะอาดได้โดยตรงใน superglobals แต่เหตุผลที่ฉันสนับสนุนให้ใช้ตัวแปรแยกต่างหากเนื่องจากการทำเช่นนั้นทำให้ง่ายต่อการมองเห็นช่องโหว่ในโค้ดเนื่องจากสิ่งใดก็ตามที่ชี้ไปยัง superglobal โดยตรงและไม่เทียบเท่ากับการฆ่าเชื้อถือว่าเป็นข้อผิดพลาดที่อันตราย .
  3. รู้ว่าข้อมูลของคุณควรมาจากไหน การอ้างอิงตัวอย่างของฉันจากด้านบนเป็นเรื่องสมเหตุสมผลอย่างยิ่งที่จะอนุญาตให้ส่งตัวแปรรูปแบบการตอบกลับผ่าน GET หรือ POST ฉันยังอนุญาตให้ส่งตัวแปร "action" ผ่านวิธีใดวิธีหนึ่ง แต่การกระทำของตัวเองมีความต้องการที่เฉพาะเจาะจงมากเป็นที่ HTTP กริยาเป็นที่ยอมรับ ตัวอย่างเช่นฟังก์ชันที่เปลี่ยนแปลงข้อมูลที่ใช้โดยบริการอาจส่งผ่าน POST เท่านั้น คำขอสำหรับข้อมูลบางประเภทที่ไม่มีสิทธิ์หรือมีสิทธิ์ต่ำ (เช่นภาพแผนที่ที่สร้างขึ้นแบบไดนามิก) อาจได้รับการตอบสนองต่อคำขอจากวิธีใดวิธีหนึ่ง

โดยสรุปจำกฎง่ายๆนี้ไว้:

ความปลอดภัยคือสิ่งที่คุณทำให้คน!

แก้ไข:

ฉันขอแนะนำคำแนะนำของ Bobince: ถ้าทำได้ให้ตั้งค่าrequest_orderพารามิเตอร์ใน php.ini เป็น "GP"; นั่นคือไม่มีส่วนประกอบของคุกกี้ แทบจะไม่มีเหตุผลที่เป็นเหตุเป็นผลสำหรับกรณีนี้ใน 98% + เนื่องจากข้อมูลคุกกี้แทบจะไม่ได้รับการพิจารณาเทียบเคียงกับสตริงการสืบค้นหรือข้อมูลภายหลัง

PS, เกร็ดเล็กเกร็ดน้อย!

ฉันรู้จักโปรแกรมเมอร์คนหนึ่งที่คิดถึง$_REQUESTสถานที่สำหรับจัดเก็บข้อมูลที่สามารถเข้าถึงได้ด้วยวิธีที่ยอดเยี่ยม ชื่อผู้ใช้และรหัสผ่านที่สำคัญพา ธ ไปยังไฟล์คุณตั้งชื่อและเก็บไว้ใน$_REQUESTไฟล์. เขารู้สึกประหลาดใจเล็กน้อย (แม้ว่าจะไม่ตลก แต่น่าเสียดาย) เมื่อฉันบอกเขาว่าตัวแปรนั้นมีพฤติกรรมอย่างไร ไม่จำเป็นต้องพูดว่าการปฏิบัตินั้นถูกยกเลิก


8

คำขอ GET ควรเป็นคำขอเฉพาะและโดยทั่วไปคำขอ POST ไม่ใช่ ซึ่งหมายความว่าข้อมูลใน$_GETและ$_POSTควรโดยทั่วไปจะใช้ในรูปแบบที่แตกต่างกัน

หากแอปพลิเคชันของคุณใช้ข้อมูลจากแอปพลิเคชัน$_REQUESTจะทำงานเหมือนกันสำหรับทั้งคำขอ GET และ POST ซึ่งละเมิดความเป็นไปของ GET


1
แต่ไม่ได้ขึ้นอยู่กับการนำไปใช้? "Indempotent" เป็นคำใหม่สำหรับฉัน แต่ถ้าฉันเข้าใจมันอย่างถูกต้องมันจะเป็นเรื่องง่ายที่จะจินตนาการถึงการสร้างสถานการณ์ GET ที่ไม่ผ่อนปรน ตัวอย่างเช่นโดยทั่วไปตัวนับหน้าจะเพิ่มขึ้นทุกครั้งที่คุณขอ URL ที่กำหนด
sprugman

1
@sprugman - เช่นกันคุณสามารถมีสถานการณ์ที่คุณมีทั้งข้อมูล GET และข้อมูลPOST ในคำขอเดียวกันซึ่งในกรณีนี้วิธีการร้องขอจะไม่มีความหมายเป็นหลักเมื่อกำหนดบริบทด้วยข้อมูลคำขอ
zombat

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

@sprugman - แนวคิดทั่วไปที่นี่คือคุณไม่ควรมีคำขอ GET ที่แก้ไขข้อมูล ตัวอย่างทั่วไปของสาเหตุที่ไม่ดีคือเว็บสไปเดอร์ที่รวบรวมข้อมูลไซต์ของคุณและไปตามลิงก์ที่แก้ไขข้อมูลโดยไม่ได้ตั้งใจ ตัวอย่างเช่นลิงก์ "ตั้งค่าสถานะ" ในโพสต์ SO
Eric Petroelje

นั่นเป็นตัวอย่างที่ไม่สำคัญ ถ้าฉันใช้ GET ผ่าน ajax เพราะเร็วกว่า (ตามที่แนะนำในโพสต์นี้เกี่ยวกับ carsonified carsonified.com/blog/dev/the-definitive-guide-to-get-vs-post )
sprugman

7

มันคลุมเครือ คุณไม่รู้จริงๆว่าข้อมูลมีต่อคุณอย่างไรเนื่องจากมีข้อมูลโพสต์รับและคุกกี้ ฉันไม่จำเป็นต้องคิดว่านั่นเป็นเรื่องเลวร้ายเสมอไปเว้นแต่คุณจะต้องรู้หรือ จำกัด วิธีการจัดส่ง


3

ฉันชอบใช้มันจริงๆ ช่วยให้คุณมีความยืดหยุ่นในการใช้ GET หรือ POST ซึ่งมีประโยชน์สำหรับสิ่งต่างๆเช่นรูปแบบการค้นหาที่ข้อมูลเวลาส่วนใหญ่ถูกโพสต์ แต่บางครั้งคุณอาจต้องการพูดลิงก์ไปยังการค้นหาหนึ่ง ๆ เพื่อให้คุณสามารถใช้พารามิเตอร์ GET แทนได้ .

นอกจากนี้หากคุณดูภาษาอื่น ๆ อีกมากมาย (เช่น ASP.NET) ภาษาเหล่านี้จะไม่มีความแตกต่างระหว่างตัวแปร GET และ POST เลย

ETA :

ฉันไม่เคยใช้ REQUEST เพื่อรับค่า COOKIE แต่ฉันคิดว่า Kyle Butt เป็นจุดที่ดีในความคิดเห็นในโพสต์นี้เกี่ยวกับเรื่องนี้ ไม่ควรใช้ REQUEST เพื่อรับค่า COOKIE ฉันเชื่อว่าเขาพูดถูกว่ามีศักยภาพที่แท้จริงในการปลอมแปลงคำขอข้ามไซต์หากคุณทำเช่นนั้น

นอกจากนี้ลำดับการโหลดสิ่งต่างๆใน REQUEST จะถูกควบคุมโดยพารามิเตอร์คอนฟิกูเรชันใน php.ini (variable_order และ request_order) ดังนั้นหากคุณมีตัวแปรเดียวกันที่ส่งผ่านทั้ง POST และ GET ตัวแปรใดที่เข้าสู่ REQUEST ได้ขึ้นอยู่กับการตั้งค่า ini เหล่านั้น สิ่งนี้อาจส่งผลต่อความสามารถในการพกพาหากคุณขึ้นอยู่กับคำสั่งซื้อเฉพาะและการตั้งค่าเหล่านั้นได้รับการกำหนดค่าให้แตกต่างจากที่คุณคาดไว้


นั่นเป็นความผิดพลาดที่ยิ่งใหญ่ คุณจะรับประกันได้อย่างไรว่ามีการดำเนินการที่ไม่เกี่ยวข้องกับ POST
Kyle Butt

1
@Kyle - โดยไม่ใช้มันสำหรับการกระทำที่ไม่ได้ตั้งใจ แน่นอนฉันจะไม่ใช้มันสำหรับทุกสิ่งเพียงแค่ชี้ให้เห็นว่ามันมีประโยชน์เช่นสำหรับการค้นหาที่ฉันพูดถึงในตัวอย่างของฉัน
Eric Petroelje

1
ความคิดมหัศจรรย์ที่ว่า _POST ปลอดภัยและ _GET ไม่ต้องไป หากฉันใช้ซอฟต์แวร์ของคุณไม่ถูกต้องแสดงว่ามีความแตกต่างน้อยมาก (ถ้ามี) สำหรับฉันในการส่งคำขอ POST เทียบกับคำขอ GET ความปลอดภัยอยู่ที่สิ่งที่คุณทำกับข้อมูลไม่ใช่ที่มา สำหรับการหาประโยชน์จาก XSS / Request แบบธรรมดามันเป็นไปได้ทั้งหมดที่จะใช้ _REQUEST สำหรับค่าที่ใช้ได้กับ POST หรือ GET เท่านั้นและใช้ _POST สำหรับสิ่งที่ควรโพสต์เท่านั้น สามัญสำนึกไม่ใช่การใช้ superglobal วิเศษ
เผยแพร่

1
@Kyle - ฉันยังไม่เห็นว่าคุณไม่สามารถทำสิ่งที่คุณพูดถึงได้อย่างง่ายดายเช่นเดียวกับการใช้ curl () หรือโพสต์ ajax เพื่อส่งผ่านข้อมูลเดียวกันนั้นผ่าน POST และ COOKIE ไม่ว่าคุณจะใช้ REQUEST, GET, POST หรือ COOKIE ในที่สุดข้อมูลทั้งหมดก็มาจากไคลเอนต์และอาจถูกปลอมได้ตลอดเวลา
Eric Petroelje

1
@zombat: คำขอ curl ที่คุณสร้างขึ้นจะไม่ถูกล็อกอินในฐานะผู้ใช้ที่มีช่องโหว่ ลิงก์ที่คุณสร้างและวางบนไซต์ของคุณจะ @Dereleased: มันไม่ใช่ความคิดที่วิเศษและยังมีช่องโหว่มากมายกับ GET แต่การเชื่อถือ POST จากผู้ใช้ที่เข้าสู่ระบบจะปลอดภัยกว่า GET จากผู้ใช้ที่ล็อกอิน
Kyle Butt

2

สิ่งสำคัญคือต้องเข้าใจว่าเมื่อใดควรใช้โพสต์เมื่อใดควรใช้ GET และเมื่อใดควรใช้คุกกี้ ด้วย $ _REQUEST มูลค่าที่คุณกำลังมองหาอาจมาจากค่าใดก็ได้ หากคุณคาดว่าจะได้รับค่าจาก POST หรือ GET หรือจาก COOKIE ผู้อ่านโค้ดของคุณจะให้ข้อมูลมากกว่าเพื่อใช้ตัวแปรเฉพาะแทน $ _REQUEST

มีคนอื่นชี้ให้เห็นด้วยว่าคุณไม่ต้องการให้ GET หรือคุกกี้ทั้งหมดถูกแทนที่เนื่องจากมีกฎข้ามไซต์ที่แตกต่างกันสำหรับกฎทั้งหมดเช่นหากคุณส่งคืนข้อมูล ajax ในขณะที่ใช้ $ _REQUEST คุณจะเสี่ยง เพื่อโจมตีสคริปต์ข้ามไซต์


2

การใช้เวลาเพียงอย่างเดียว$_REQUESTไม่ใช่ความคิดที่ไม่ดีคือ GET

  • หากคุณใช้เพื่อโหลดค่า POST คุณอาจเสี่ยงต่อการปลอมแปลงคำขอข้ามไซต์
  • หากคุณใช้เพื่อโหลดค่าคุกกี้คุณอาจเสี่ยงต่อการปลอมแปลงคำขอข้ามไซต์อีกครั้ง

และถึงแม้จะใช้ GET $_GETก็ยังพิมพ์ได้สั้นกว่า$_REQUEST;)


แม้ว่าฉันจะเห็นด้วยกับคุณ แต่ฉันคิดว่าสิ่งสำคัญคือต้องทราบว่าเหตุใดจึงเป็นจริงและ / หรืออันตรายควรใช้$_POSTเมื่อข้อมูลสำคัญคือ POSTDATA ควรใช้$_REQUESTเมื่อข้อมูลไม่เชื่อเรื่องพระเจ้ากับ HTTP Verb ที่ใช้ ในกรณีเหล่านี้ควรทำความสะอาดข้อมูลอินพุตทั้งหมดอย่างระมัดระวัง
เผยแพร่

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

ง่ายกว่ามากในการละเมิด GET สำหรับการปลอมแปลง ตัวอย่างเช่นคุณสามารถมีแท็ก img พร้อมกับ src ที่ตั้งค่าด้วยพารามิเตอร์ที่คุณต้องการ มันจะทำงานโดยที่ผู้ใช้ไม่เคยรู้ว่ามันอยู่ที่นั่น
Jani Hartikainen

0

ฉันอาจใช้เฉพาะในกรณีที่คุณต้องการดึง url หรือชื่อโฮสต์ปัจจุบัน แต่สำหรับการแยกวิเคราะห์ข้อมูลจาก URL นั้นจริง ๆ เช่นพารามิเตอร์ที่ใช้เครื่องหมาย & อาจไม่ใช่ความคิดที่ดี โดยทั่วไปคุณไม่ต้องการใช้คำอธิบายที่คลุมเครือเกี่ยวกับสิ่งที่คุณกำลังพยายามทำ หากคุณต้องการเจาะจงว่า $ _REQUEST ไม่ดีตรงไหนถ้าคุณไม่จำเป็นต้องเจาะจงก็อย่าลังเลที่จะใช้มัน ฉันจะคิด.


คุณพยายามจะพูดอะไร? คุณสับสน$_REQUESTกับ$_SERVER['QUERY_STRING']?
เผยแพร่

0

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

สามารถใช้ $ _REQUEST ได้อย่างสะดวกเมื่อสคริปต์ของคุณอาจตอบสนองต่อ GET หรือ POST ในลักษณะเดียวกัน ฉันจะเถียงว่านี่น่าจะเป็นกรณีที่หายากมากและในกรณีส่วนใหญ่สองฟังก์ชันที่แยกจากกันเพื่อจัดการกับสองแนวคิดที่แยกจากกันหรืออย่างน้อยที่สุดก็ควรตรวจสอบวิธีการและเลือกตัวแปรที่ถูกต้อง การไหลของโปรแกรมมักจะทำตามได้ง่ายกว่ามากเมื่อไม่จำเป็นต้องอ้างอิงโยงว่าตัวแปรอาจมาจากที่ใด ใจดีกับผู้ที่ต้องรักษารหัสของคุณในเวลา 6 เดือน มันอาจจะเป็นคุณ.

นอกเหนือจากปัญหาด้านความปลอดภัยและ WTF ที่เกิดจากคุกกี้และตัวแปรสภาพแวดล้อมในตัวแปร REQUEST (อย่าให้ฉันเริ่มใช้ GLOBAL) ให้พิจารณาสิ่งที่อาจเกิดขึ้นในอนาคตหาก PHP เริ่มสนับสนุนวิธีการอื่น ๆ เช่น PUT และ DELETE แม้ว่าจะไม่น่าเป็นไปได้อย่างมากที่สิ่งเหล่านี้จะรวมเข้ากับ REQUEST superglobal แต่ก็เป็นไปได้ว่าอาจรวมเป็นตัวเลือกในการตั้งค่า variable_order ดังนั้นคุณจึงไม่รู้เลยว่า REQUEST ถืออะไรและสิ่งใดมีความสำคัญเหนือกว่าโดยเฉพาะอย่างยิ่งหากโค้ดของคุณถูกปรับใช้บนเซิร์ฟเวอร์ของบุคคลที่สาม

POST ปลอดภัยกว่า GET หรือไม่? ไม่จริง จะดีกว่าถ้าใช้ GET ในที่ที่ใช้งานได้จริงเพราะง่ายต่อการดูในบันทึกของคุณว่าแอปพลิเคชันของคุณถูกใช้ประโยชน์อย่างไรเมื่อถูกโจมตี POST ดีกว่าสำหรับการดำเนินการที่มีผลต่อสถานะโดเมนเนื่องจากโดยทั่วไปสไปเดอร์ไม่ปฏิบัติตามและกลไกการดึงข้อมูลเชิงคาดการณ์จะไม่ลบเนื้อหาทั้งหมดของคุณเมื่อคุณลงชื่อเข้าใช้ CMS อย่างไรก็ตามคำถามไม่ได้เกี่ยวกับข้อดีของ GET vs POST แต่เป็นเรื่องเกี่ยวกับวิธีที่ผู้รับควรปฏิบัติต่อข้อมูลขาเข้าและทำไมการรวมเข้าด้วยกันจึงไม่ดีดังนั้นนี่จึงเป็นเพียง BTW เท่านั้น


0

ฉันคิดว่าไม่มีปัญหา$_REQUESTแต่เราต้องระมัดระวังในการใช้เนื่องจากเป็นการรวบรวมตัวแปรจาก 3 แหล่ง (GPC)

ฉันเดาว่า$_REQUESTยังสามารถทำให้โปรแกรมเก่าเข้ากันได้กับ php เวอร์ชันใหม่ แต่ถ้าเราเริ่มโปรเจ็กต์ใหม่ (รวมถึงไลบรารีใหม่) ฉันคิดว่าเราไม่ควรใช้$_REQUESTอีกต่อไปเพื่อให้โปรแกรมชัดเจนขึ้น เราควรพิจารณาลบการใช้งาน$_REQUESTและแทนที่ด้วยฟังก์ชัน wrapper เพื่อทำให้โปรแกรมมีน้ำหนักเบาลงโดยเฉพาะอย่างยิ่งในการประมวลผลข้อมูลข้อความที่ส่งจำนวนมากเนื่องจาก$_REQUESTมีสำเนาของ$_POSTไฟล์.

// delete $_REQUEST when program execute, the program would be lighter 
// when large text submitted
unset($_REQUEST);

// wrapper function to get request var
function GetRequest($key, $default = null, $source = '') 
{
  if ($source == 'get') {
    if (isset($_GET[$key])) { 
      return $_GET[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'post') {
    if (isset($_POST[$key])) { 
      return $_POST[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'cookie') {
    if (isset($_COOKIE[$key])) { 
      return $_COOKIE[$key]; 
    } else { 
      return $default; 
    }
  } else {
    // no source specified, then find in GPC
    if (isset($_GET[$key])) {
      return $_GET[$key];     
    } else if (isset($_POST[$key])) {
      return $_POST[$key]; 
    } else if (isset($_COOKIE[$key])) {
      return $_COOKIE[$key]; 
    } else {
      return $default; 
    } 
  }
}

0

Darren Cook: "เนื่องจาก php 5.3 เริ่มต้น php.ini ระบุว่าใส่เฉพาะข้อมูล GET และ POST $_REQUESTเท่านั้นดูphp.net/request_orderฉันเพิ่งสะดุดกับตัวแบ่งความเข้ากันได้แบบย้อนหลังนี้เมื่อคาดว่าข้อมูลคุกกี้จะอยู่ใน$_REQUESTและสงสัยว่าทำไมมันถึงไม่ ' ไม่ทำงาน! "

ว้าว ... เพียงแค่มีบางส่วนของสคริปต์ของฉันหยุดการทำงานเนื่องจากการอัพเกรด PHP 5.3 ทำสิ่งเดียวกัน: สมมติว่าคุกกี้จะถูกตั้งค่าเมื่อใช้$_REQUESTตัวแปร ด้วยการอัปเกรดที่หยุดทำงาน

ตอนนี้ฉันเรียกค่าคุกกี้แยกกันโดยใช้$_COOKIE["Cookie_name"]...


-1

ปัญหาหลักคือมันมีคุกกี้ตามที่คนอื่นพูด

ใน PHP 7 คุณสามารถทำได้:

$request = array_merge($_GET ?? [], $_POST ?? []);

วิธีนี้จะช่วยหลีกเลี่ยงปัญหาคุกกี้และทำให้คุณได้อาร์เรย์ว่างเปล่าที่แย่ที่สุดและการควบรวมกิจการของ $ _GET และ $ _POST จะมีผลเหนือกว่า หากคุณไม่ใส่ใจกับการอนุญาตให้มีการแทรกพารามิเตอร์ URL ผ่านสตริงการสืบค้นมากเกินไปก็ค่อนข้างสะดวก


ผู้ที่เลือกที่จะลงคะแนนโปรดอธิบายเพื่อความจรรโลงใจของฉัน
amh15

-2

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


4
ความปลอดภัยระหว่าง $ _POST และ $ _GET ไม่มีความแตกต่างกันนอกจากคุณจะพิมพ์คำขอ POST ลงในแถบ URL ของเบราว์เซอร์ไม่ได้ ใช้เวลาเพียง 5 วินาทีในการแส้คำขอ cURL บรรทัดคำสั่งโดยใช้ POST
zombat

3
@ Zombat: เราจำเป็นต้องเริ่มแคมเปญบางอย่างเพื่อโน้มน้าวผู้คนว่า POST ไม่ปลอดภัยโดยเนื้อแท้หรือปลอดภัยกว่า GET ความปลอดภัยคือวิธีที่คุณจัดการกับข้อมูลไม่ใช่สิ่งที่ HTTP Verb ใช้เพื่อรับข้อมูลนั้น
เผยแพร่

@Dereleased - ฉันขอเสนอภาพดูโอโทนที่เป็นสัญลักษณ์ของก้อนเมฆที่มีสายฟ้าเพื่อแสดงถึงอินเทอร์เน็ตโดยมีคำว่า "CHANGE" อยู่ข้างใต้
zombat

1
@GuyT: นั่นเป็นมุมมองที่แคบมาก ไม่ใช่แค่ความ "ปลอดภัย" เท่านั้น แต่เป็นความลับเพียงใด พารามิเตอร์ GET สามารถแสดงเป็นการเติมข้อความอัตโนมัติใน url ของเบราว์เซอร์หรือแม้แต่ประวัติของเบราว์เซอร์ นอกจากนี้ความปลอดภัยไม่ได้จบลงด้วยเบราว์เซอร์ ตัวอย่างเช่นเซิร์ฟเวอร์จำนวนมากบันทึก URL http ดังนั้นสิ่งใดก็ตามใน url จะถูกบันทึกเช่น การมีชื่อผู้ใช้ / รหัสผ่านปรากฏในบันทึกจะสร้างความแตกต่าง ในด้านความปลอดภัยหลีกเลี่ยงการส่งข้อมูลที่ละเอียดอ่อนเป็นพารามิเตอร์ GET เสมอ
สแตน

1
บันทึกการเข้าถึง Apache โดยเฉพาะ URL คำขอใด ๆ จะถูกบันทึกและทุกคนที่สามารถเข้าถึงบันทึกจะสามารถเห็นข้อมูลประจำตัวของคุณที่ส่งผ่านมา
สแตน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.