Có gì sai khi sử dụng $ _REQUEST []?


116

Tôi đã thấy một số bài đăng trên đây nói rằng không sử dụng $_REQUESTbiến. Tôi thường không làm, nhưng đôi khi nó rất tiện lợi. Có gì sai với nó?


2
Xem câu hỏi và câu trả lời liên quan: stackoverflow.com/questions/1149118/…
Gordon

2
Vì php 5.3, php.ini mặc định cho biết chỉ có dữ liệu GET và POST được đưa vào $_REQUEST. Xem php.net/request_order Tôi vừa vấp phải lỗi tương thích ngược này khi mong đợi dữ liệu cookie được đưa vào $_REQUESTvà tự hỏi tại sao nó không hoạt động! Vì vậy, lý do lớn nhất để tránh sử dụng $ _REQUEST hiện tại là tập lệnh của bạn không thể request_ordertự thiết lập (đúng PHP_INI_PERDIRnhư vậy), vì vậy thay đổi php.ini có thể dễ dàng phá vỡ các giả định mà tập lệnh của bạn được xây dựng. Tốt hơn nên đưa những giả định đó trực tiếp vào kịch bản của bạn.
Darren Cook

Câu trả lời:


184

Hoàn toàn không có gì sai khi lấy đầu vào từ cả hai $_GET$_POSTtheo cách kết hợp. Trên thực tế, đó là những gì bạn hầu như luôn muốn làm:

  • đối với một yêu cầu đơn giản thường được gửi qua GET, có khả năng lượng dữ liệu bạn muốn sẽ không vừa với một URL, vì vậy nó đã bị biến đổi thành một yêu cầu POST như một vấn đề thực tế.

  • đối với một yêu cầu có tác dụng thực sự, bạn phải kiểm tra xem nó có được gửi bằng phương thức POST hay không. Nhưng cách để làm điều đó là kiểm tra $_SERVER['REQUEST_METHOD']một cách rõ ràng, không dựa vào $_POSTviệc trống rỗng để lấy GET. Và dù sao nếu là phương pháp POST, bạn vẫn có thể muốn lấy một số tham số truy vấn ra khỏi URL.

Không, vấn đề $_REQUESTkhông liên quan gì đến việc kết hợp các tham số GET và POST. Theo mặc định, nó cũng bao gồm $_COOKIE. Và cookie thực sự không giống như các thông số gửi biểu mẫu chút nào: bạn hầu như không bao giờ muốn coi chúng như một thứ giống nhau.

Nếu bạn vô tình nhận được một tập hợp cookie trên trang web của mình có cùng tên với một trong các tham số biểu mẫu của bạn, thì các biểu mẫu dựa vào tham số đó sẽ ngừng hoạt động bình thường một cách bí ẩn do các giá trị cookie ghi đè các tham số dự kiến. Điều này rất dễ thực hiện nếu bạn có nhiều ứng dụng trên cùng một trang web và có thể rất khó để gỡ lỗi khi bạn chỉ có một vài người dùng với cookie cũ mà bạn không sử dụng nữa và phá vỡ biểu mẫu theo những cách không. -một người khác có thể sinh sản.

Bạn có thể thay đổi hành vi này thành thứ tự hợp lý hơn GP(không C) với cấu hình request_order trong PHP 5.3. Nếu điều này là không thể, cá nhân tôi sẽ tránh $_REQUESTvà nếu tôi cần một mảng GET + POST kết hợp, hãy tạo nó theo cách thủ công.


2
Những tình huống này (dữ liệu quá lâu để được gửi qua GET) là một ngoại lệ, không phải là một quy tắc
Bến James

1
Câu trả lời rất hay. Tôi cũng nhận thấy rằng với các khung như Zend Framework, GET và POST params được kết hợp thành 1 đối tượng yêu cầu. Nó không bao giờ đánh tôi cho đến khi tôi đọc bài viết của bạn.
Jay Sidri

Theo mặc định, cấu hình request_order được đặt thành "GP" trong php.ini kể từ PHP 5.4+, vì vậy tôi muốn nói rằng hãy sử dụng nó ... nhưng như mọi khi, hãy tiến hành một cách thận trọng.
bcmoney

nếu $ _POST là a="foo"và $ _COOKIE a="bar", thì sẽ có bất kỳ ghi đè / xung đột nào ở đây không?
Gỉ sét

75

Tôi đã tìm hiểu một số bài đăng của nhóm tin trên PHP Internals và tìm thấy một cuộc thảo luận thú vị về chủ đề này. Chủ đề ban đầu là về một cái gì đó khác, nhưng nhận xét của Stefan Esser, một chuyên gia bảo mật (nếu không phải ) trong thế giới PHP đã chuyển cuộc thảo luận về các tác động bảo mật của việc sử dụng $ _REQUEST cho một số bài đăng.

Trích dẫn Stefan Esser trên PHP Internals

$ _REQUEST là một trong những điểm yếu thiết kế lớn nhất trong PHP. Mọi ứng dụng sử dụng $ _REQUEST có lẽ rất dễ gặp phải các vấn đề về Truy vấn Yêu cầu Trang web Chậm Chậm. (Về cơ bản, điều này có nghĩa là nếu cookie có tên (tuổi) tồn tại, nó sẽ luôn ghi đè lên nội dung GET / POST và do đó các yêu cầu không mong muốn sẽ được thực hiện)

trả lời sau cho cùng một chủ đề

Nó không phải là về thực tế là ai đó có thể giả mạo GET, POST; Các biến COOKIE. Đó là thực tế là COOKIEs sẽ ghi đè dữ liệu GET và POST trong REQUEST.

Do đó, tôi có thể lây nhiễm vào trình duyệt của bạn một cookie ví dụ: action = logout và kể từ ngày đó, bạn không thể sử dụng ứng dụng này nữa vì REQUEST [action] sẽ bị đăng xuất vĩnh viễn (cho đến khi bạn xóa cookie theo cách thủ công).

Và để lây nhiễm COOKIE cho bạn rất đơn giản ...
a) Tôi có thể sử dụng XSS vuln trong bất kỳ ứng dụng nào trên tên miền phụ
b) Đã từng thử đặt cookie cho * .co.uk hoặc * .co.kr khi bạn sở hữu một tên miền duy nhất ở đó?
c) Miền chéo khác theo bất kỳ cách nào ...

Và nếu bạn tin rằng đây không phải là vấn đề thì tôi có thể nói với bạn rằng có một khả năng đơn giản là đặt cookie fe * .co.kr dẫn đến một số phiên bản PHP chỉ trả về các trang trắng. Hãy tưởng tượng: Chỉ một cookie duy nhất để giết tất cả các trang PHP trong * .co.kr

Và bằng cách đặt ID phiên bất hợp pháp trong cookie hợp lệ cho * .co.kr trong biến có tên + PHPSESSID = lậu, bạn vẫn có thể DOS cho mọi ứng dụng PHP ở Hàn Quốc bằng các phiên PHP ...

Cuộc thảo luận tiếp tục cho một vài bài đăng nữa và rất thú vị để đọc.


Như bạn có thể thấy, vấn đề chính của $ _REQUEST không phải là nó có dữ liệu từ $ _GET và $ _POST, mà còn từ $ _COOKIE. Một số người khác trong danh sách đề nghị thay đổi thứ tự mà $ _REQUEST được điền, ví dụ: điền nó bằng $ _COOKIE trước, nhưng điều này có thể dẫn đến nhiều vấn đề tiềm ẩn khác, chẳng hạn như với xử lý Phiên .

Bạn có thể $ _COOKIES hoàn toàn omit từ $ mặc dù toàn cầu _REQUEST, do đó nó không được ghi đè bởi bất kỳ của các mảng khác (trong thực tế, bạn có thể giới hạn nó đến bất kỳ sự kết hợp của nội dung tiêu chuẩn của nó, giống như hướng dẫn PHP trên variable_order thiết lập ini nói với chúng tôi:

biến_order Đặt thứ tự phân tích cú pháp biến EGPCS (Môi trường, Nhận, Đăng, Cookie và Máy chủ). Ví dụ: nếu biến_order được đặt thành "SP" thì PHP sẽ tạo siêu cầu thủ $ _SERVER và $ _POST, nhưng không tạo $ _ENV, $ _GET và $ _COOKIE. Đặt thành "" có nghĩa là không có siêu cầu thủ nào được đặt.

Nhưng một lần nữa, bạn cũng có thể cân nhắc việc không sử dụng $ _REQUEST hoàn toàn, đơn giản vì trong PHP, bạn có thể truy cập Môi trường, Nhận, Đăng, Cookie và Máy chủ trong phạm vi toàn cầu của riêng chúng và có ít véc tơ tấn công hơn. Bạn vẫn phải khử trùng dữ liệu này, nhưng đó là một điều ít phải lo lắng hơn.


Bây giờ bạn có thể tự hỏi, tại sao $ _REQUEST lại tồn tại và tại sao nó không bị xóa. Điều này cũng được hỏi trên PHP Internals. Trích dẫn Rasmus Lerdorf về Tại sao $ _REQUEST tồn tại? trên PHP Internals

Càng loại bỏ nhiều thứ như thế này, mọi người càng khó chuyển nhanh sang các phiên bản PHP mới hơn, nhanh hơn và an toàn hơn. Điều đó gây ra sự thất vọng cho mọi người hơn là một vài tính năng kế thừa "xấu xí". Nếu có một lý do kỹ thuật, hiệu suất hoặc bảo mật phù hợp, thì chúng ta cần xem xét kỹ lưỡng. Trong trường hợp này, điều chúng ta nên xem xét không phải là chúng ta có nên xóa $ _REQUEST hay không mà là liệu chúng ta có nên xóa dữ liệu cookie khỏi nó hay không. Nhiều cấu hình đã làm điều đó, bao gồm tất cả cấu hình của riêng tôi và có lý do bảo mật hợp lệ mạnh mẽ để không bao gồm cookie trong $ _REQUEST. Hầu hết mọi người sử dụng $ _REQUEST có nghĩa là NHẬN hoặc ĐĂNG, không nhận ra rằng nó cũng có thể chứa cookie và những kẻ xấu như vậy có thể thực hiện một số thủ thuật chèn cookie và phá vỡ các ứng dụng ngây thơ.

Dù sao, hy vọng rằng làm sáng tỏ một số điều.


1
+1 điều tốt để xem một số thảo luận về điều này ... Tôi nghĩ rằng tôi đã phát điên!
bobince

2
Tôi nghĩ rằng cuộc thảo luận đó đã hơi quá khái quát. Vấn đề thực tế là sự không biết của nhà phát triển, không phải sự tồn tại của cookie trong $ _REQUEST. Ví dụ: PHPSESSID đã được sửa chữa sẽ được đặt lại bằng cookie cho mỗi miền với mã xử lý phiên hiện đại. Và đối với một số ứng dụng, một vars yêu cầu ghi đè cookie có thể thực sự được mong muốn (ví dụ: sort_order = ASC ghi đè biểu mẫu tìm kiếm GET var). Mặc dù mã hóa trong hành vi như vậy rõ ràng là hợp lý hơn.
mario

1
Bài đăng rất toàn diện, đây phải là câu trả lời. Có lẽ người sợ bài dài;)
Dũng Nguyễn

Đáng buồn thay, Rasmus đã nhận xét về điều này vào năm 2009, nhưng $ _REQUEST về cơ bản vẫn giống như bây giờ, vào năm 2015.
Kzqai 21/02/15

10

$_REQUESTđề cập đến tất cả các loại yêu cầu (GET, POST, v.v.). Điều này đôi khi hữu ích, nhưng thường tốt hơn nếu chỉ định phương thức chính xác ($ _GET, $ _POST, v.v.).


19
Câu trả lời này mô tả $ _REQUEST là gì, nhưng nó không trả lời câu hỏi.
zombat

1
Anh ấy nói rằng tốt hơn hết là bạn nên biết loại yêu cầu nào sẽ đến và viết mã cho yêu cầu cụ thể đó.
Polaris878

8

$_REQUEST thường được coi là có hại vì cùng một lý do là các phép biến đổi dữ liệu từ đơn giản đến trung bình-phức tạp thường được thực hiện trong mã ứng dụng thay vì được khai báo trong SQL: một số lập trình viên rất tệ.

Do đó, nếu một người có xu hướng sử dụng $_REQUESTở mọi nơi, tôi có thể làm bất cứ điều gì thông qua GET mà tôi có thể thông qua POST, nghĩa là thiết lập<img> thẻ trên trang web (độc hại) của tôi khiến người dùng đăng nhập vào mô-đun thương mại điện tử của bạn để mua sản phẩm một cách âm thầm, hoặc tôi có thể khiến họ nhấp vào các liên kết dẫn đến các hành động nguy hiểm hoặc tiết lộ thông tin nhạy cảm (có thể là đối với tôi).

Tuy nhiên, điều này là do một lập trình viên PHP mới làm quen, hoặc ít nhất là thiếu kinh nghiệm, mắc những lỗi đơn giản. Trước hết, hãy biết khi nào dữ liệu thuộc loại nào là phù hợp. Ví dụ: tôi có một dịch vụ web có thể trả lại phản hồi ở dạng URLEncoding, XML hoặc JSON. Ứng dụng quyết định cách định dạng phản hồi bằng cách kiểm tra tiêu đề HTTP_ACCEPT, nhưng có thể bị ép buộc thành một phản hồi cụ thể bằng cách gửi formattham số.

Khi kiểm tra nội dung của tham số định dạng, nó có thể được gửi qua chuỗi truy vấn hoặc postdata, tùy thuộc vào vô số yếu tố, không quan trọng nhất là liệu các ứng dụng gọi điện có muốn "& format = json" trộn lẫn với yêu cầu của nó hay không. Trong trường hợp này, $_REQUESTrất tiện lợi vì nó giúp tôi không phải gõ một cái gì đó như thế này:

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

Tôi sẽ không lan man thêm nữa, nhưng đủ để nói rằng $_REQUEST việc sử dụng không được khuyến khích bởi vì nó vốn dĩ rất nguy hiểm - nó chỉ là một công cụ khác thực hiện chính xác những gì được yêu cầu về nó, cho dù bạn có hiểu những hàm ý đó hay không - đó là quyết định kém, lười biếng hoặc thiếu hiểu biết của một lập trình viên kém, lười biếng hoặc thiếu kinh nghiệm gây ra sự cố này.

Cách sử dụng $_REQUESTan toàn


  1. Biết dữ liệu của bạn : Bạn nên có một số kỳ vọng về loại dữ liệu bạn sẽ nhận được, vì vậy hãy khử trùng nó cho phù hợp. Dữ liệu cho một cơ sở dữ liệu? addslashes()hoặc *_escape_string(). Sắp hiển thị lại cho người dùng? htmlentities()hoặc htmlspecialchars(). Mong đợi dữ liệu số? is_numeric()hoặc ctype_digit(). Trong thực tế,filter_input() và các chức năng liên quan của nó được thiết kế để không làm gì khác ngoài việc kiểm tra và làm sạch dữ liệu. Sử dụng những công cụ này, luôn luôn.
  2. Không truy cập trực tiếp vào dữ liệu superglobals do người dùng cung cấp . Tạo thói quen làm sạch dữ liệu của bạn mọi lúc và di chuyển dữ liệu của bạn sang các biến sạch, ngay cả khi nó chỉ là $post_clean. Ngoài ra, bạn có thể chỉ cần làm sạch trực tiếp trong superglobals, nhưng lý do tôi ủng hộ việc sử dụng một biến riêng biệt là vì làm như vậy giúp dễ dàng phát hiện ra các lỗ hổng trong mã, vì bất kỳ thứ gì trỏ trực tiếp đến superglobal và không tương đương với nó đều được coi là một lỗi nguy hiểm .
  3. Biết dữ liệu của bạn sẽ đến từ đâu. Tham khảo ví dụ của tôi từ trên, hoàn toàn hợp lý khi cho phép biến định dạng phản hồi được gửi qua GET hoặc POST. Tôi cũng cho phép biến "action" được gửi qua một trong hai phương thức. Tuy nhiên, bản thân các hành động có các yêu cầu rất cụ thể về việc chấp nhận Động từ HTTP . Ví dụ: các chức năng thực hiện thay đổi đối với dữ liệu được sử dụng bởi dịch vụ chỉ có thể được gửi qua POST. Yêu cầu đối với một số loại dữ liệu không phải hoặc đặc quyền thấp (chẳng hạn như hình ảnh bản đồ được tạo động) có thể được phục vụ theo yêu cầu từ một trong hai phương pháp.

Tóm lại, hãy nhớ quy tắc đơn giản này:

BẢO MẬT LÀ NHỮNG GÌ BẠN LÀM ĐƯỢC NÓ, CON NGƯỜI!

BIÊN TẬP:

Tôi mạnh mẽ đề nghị tư vấn bobince của: nếu bạn có thể, thiết lập các request_ordertham số trong php.ini để "GP"; nghĩa là, không có thành phần cookie. Hầu như không có lý do hợp lý nào cho điều này trong 98% + trường hợp, vì dữ liệu cookie hầu như không bao giờ được coi là có thể so sánh với chuỗi truy vấn hoặc với dữ liệu đăng.

Tái bút, Giai thoại!

Tôi biết một lập trình viên đã nghĩ $_REQUESTra một nơi để lưu trữ dữ liệu đơn giản có thể truy cập theo cách siêu toàn cầu. Tên người dùng và mật khẩu quan trọng, đường dẫn đến tệp, bạn đặt tên cho nó và nó được lưu trữ trong $_REQUEST. Anh ấy hơi ngạc nhiên (mặc dù không hài hước như vậy, thật không may) khi tôi nói cho anh ấy biết biến đó hoạt động như thế nào. Không cần phải nói, thực hành đó đã bị hạ bệ.


8

Yêu cầu GET phải là không quan trọng và yêu cầu POST nói chung là không. Điều này có nghĩa là dữ liệu trong $_GET$_POSTnói chung phải được sử dụng theo những cách khác nhau.

Nếu ứng dụng của bạn đang sử dụng dữ liệu từ $_REQUEST, nó sẽ hoạt động giống nhau đối với cả yêu cầu GET và POST, điều này vi phạm tính ưu việt của GET.


1
nhưng điều đó không phụ thuộc vào việc thực hiện? "Indempotent" là một từ mới đối với tôi, nhưng nếu tôi hiểu nó một cách chính xác, sẽ dễ dàng hình dung ra việc thiết lập một tình huống GET không phải là một cách thiếu kiên trì. Ví dụ: bộ đếm trang thường tăng lên mỗi khi bạn yêu cầu một url nhất định.
sprugman

1
@sprugman - ngoài ra, bạn có thể gặp các trường hợp mà bạn có cả dữ liệu GET dữ liệu POST trong cùng một yêu cầu, trong trường hợp đó, phương thức yêu cầu về cơ bản là vô nghĩa khi được ngữ cảnh hóa với dữ liệu yêu cầu.
zombat

sprugman, rõ ràng là bất kỳ yêu cầu GET nào cũng sửa đổi một cái gì đó vì nó được ghi lại bởi máy chủ web. Nó vẫn có thể bị thiếu trong miền của ứng dụng, nơi siêu dữ liệu này không thực sự quan trọng.
Ben James

@sprugman - ý tưởng chung ở đây là bạn không nên có yêu cầu GET sửa đổi dữ liệu. Một ví dụ điển hình về lý do tại sao điều này là xấu sẽ là một mạng nhện thu thập dữ liệu trang web của bạn và đi theo các liên kết vô tình sửa đổi dữ liệu. Ví dụ: liên kết "cờ" trên một bài đăng SO.
Eric Petroelje

Đó là một ví dụ tầm thường. Còn nếu tôi đang sử dụng GET qua ajax thì sao vì nó nhanh hơn (như được đề xuất trong bài đăng này trên caronified caronified.com/blog/dev/the-definitive-guide-to-get-vs-post ).
sprugman

7

Nó mơ hồ. Bạn không thực sự biết dữ liệu đến với bạn như thế nào vì nó mang theo dữ liệu đăng, nhận và cookie. Tôi không nhất thiết nghĩ đó luôn là một điều xấu, trừ khi bạn cần biết hoặc hạn chế phương thức giao hàng.


3

Tôi thực sự thích sử dụng nó. Nó cung cấp cho bạn sự linh hoạt khi sử dụng GET hoặc POST có thể hữu ích cho những thứ như biểu mẫu tìm kiếm trong đó phần lớn thời gian dữ liệu được POST, nhưng đôi khi bạn sẽ muốn nói liên kết đến một tìm kiếm cụ thể, vì vậy bạn có thể sử dụng tham số GET thay thế .

Ngoài ra, nếu bạn nhìn vào nhiều ngôn ngữ khác (ASP.NET chẳng hạn), chúng không phân biệt được biến GET và POST.

ETA :

Tôi chưa bao giờ sử dụng REQUEST để nhận các giá trị COOKIE, nhưng tôi nghĩ Kyle Butt đã tạo ra một điểm tuyệt vời trong các nhận xét trên bài đăng này về điều đó. Không phải là một ý kiến ​​hay khi sử dụng REQUEST để nhận các giá trị COOKIE. Tôi tin rằng anh ấy nói đúng rằng có một số tiềm năng thực sự cho việc giả mạo yêu cầu trên nhiều trang web nếu bạn làm điều đó.

Ngoài ra, thứ tự mà nội dung được tải vào REQUEST được kiểm soát bởi các tham số cấu hình trong php.ini (variable_order và request_order). Vì vậy, nếu bạn có cùng một biến được chuyển vào qua cả POST và GET, biến nào thực sự được đưa vào REQUEST phụ thuộc vào các cài đặt ini đó. Điều này có thể ảnh hưởng đến tính di động nếu bạn phụ thuộc vào một đơn đặt hàng cụ thể và những cài đặt đó được định cấu hình khác với những gì bạn mong đợi.


đó là một sai lầm khủng khiếp. Làm thế nào bạn có thể đảm bảo rằng các hành động không phải là không tập trung được thực hiện qua một BÀI ĐĂNG?
Kyle Butt

1
@Kyle - bằng cách không sử dụng nó cho các hành động không hợp lý. Tôi chắc chắn sẽ không sử dụng nó cho mọi thứ, chỉ chỉ ra rằng nó rất hữu ích, như cho các tìm kiếm như tôi đã đề cập trong ví dụ của mình.
Eric Petroelje

1
Ý tưởng kỳ diệu này rằng _POST được bảo mật và _GET không cần phải đi. Nếu tôi không sử dụng đúng phần mềm của bạn, thì tôi thấy rất ít (nếu có) sự khác biệt trong việc gửi yêu cầu POST so với yêu cầu GET. Bảo mật là ở những gì bạn làm với dữ liệu, không phải là nó đến từ đâu. Đối với các khai thác XSS / Yêu cầu đơn giản, hoàn toàn có thể nó chỉ sử dụng _REQUEST cho các giá trị hợp lệ với POST hoặc GET và chỉ sử dụng _POST cho những thứ cần được POST. Thông thường, không phải cách sử dụng siêu cầu kỳ.
Bỏ qua

1
@Kyle - Tôi vẫn chưa hiểu bằng cách nào bạn không thể thực hiện những gì bạn đề cập chỉ dễ dàng sử dụng một cái gì đó như curl () hoặc một bài đăng ajax để chuyển cùng một dữ liệu đó qua POST và COOKIE. Cho dù bạn sử dụng REQUEST, GET, POST hay COOKIE, tất cả dữ liệu cuối cùng đều đến từ máy khách và luôn có thể bị làm giả.
Eric Petroelje

1
@zombat: Yêu cầu curl mà bạn biểu mẫu sẽ không được đăng nhập với tư cách người dùng dễ bị tấn công. Liên kết mà bạn tạo và đặt trên trang web của bạn sẽ. @Dereleased: Đó không phải là suy nghĩ ma thuật, và vẫn còn nhiều lỗ hổng với GET. nhưng sẽ an toàn hơn khi tin tưởng ĐĂNG từ người dùng đã đăng nhập hơn là NHẬN từ người dùng đã đăng nhập.
Kyle Butt

2

Điều quan trọng là phải hiểu khi nào sử dụng POST, khi nào sử dụng GET và khi nào sử dụng cookie. Với $ _REQUEST, giá trị bạn đang xem có thể đến từ bất kỳ giá trị nào trong số chúng. Nếu bạn muốn nhận giá trị từ POST hoặc GET hoặc từ COOKIE, thì việc ai đó đọc mã của bạn sẽ có nhiều thông tin hơn để sử dụng biến cụ thể thay vì $ _REQUEST.

Một người khác cũng chỉ ra rằng bạn không muốn tất cả POST hoặc cookie bị GET ghi đè vì có các quy tắc trên nhiều trang web khác nhau cho tất cả chúng, ví dụ: nếu bạn trả về dữ liệu ajax trong khi sử dụng $ _REQUEST, bạn sẽ dễ bị tấn công tấn công tập lệnh trên nhiều trang web.


2

Thời gian duy nhất sử dụng $_REQUESTkhông phải là một ý tưởng tồi là với GET.

  • Nếu bạn sử dụng nó để tải các giá trị POST, bạn có nguy cơ giả mạo yêu cầu trên nhiều trang web
  • Nếu bạn sử dụng nó để tải các giá trị cookie, bạn lại có nguy cơ giả mạo yêu cầu trên nhiều trang web

Và ngay cả với GET, $_GETgõ ngắn hơn $_REQUEST;)


Mặc dù tôi đồng ý với bạn nhưng tôi nghĩ điều quan trọng cần lưu ý là tại sao điều này đúng và / hoặc nguy hiểm: người ta nên sử dụng $_POSTkhi điều quan trọng là dữ liệu phải là POSTDATA. Bạn nên sử dụng $_REQUESTkhi dữ liệu không phù hợp với Động từ HTTP được sử dụng. Trong tất cả các trường hợp này, người ta nên khử trùng cẩn thận tất cả dữ liệu đầu vào.
Bỏ qua

1
Tôi không hiểu nguồn dữ liệu có liên quan như thế nào đến khả năng giả mạo yêu cầu trên nhiều trang web. Kẻ tấn công có thể đặt tham số POST một cách hoàn hảo dễ dàng bằng cách cung cấp cho người dùng biểu mẫu POST được trỏ vào trang web của bạn; bạn sẽ cần các biện pháp bảo vệ chống XSRF giống nhau bất kể việc gửi đến từ GET hay POST.
bobince

Việc lạm dụng GET để giả mạo dễ dàng hơn nhiều. Ví dụ: bạn có thể chỉ cần có một thẻ img với bộ src của nó với các thông số bạn muốn. Nó sẽ hoạt động mà người dùng không bao giờ biết nó đã ở đó.
Jani Hartikainen

0

Tôi có thể chỉ được sử dụng nếu bạn muốn truy xuất url hoặc tên máy chủ hiện tại, nhưng để thực sự phân tích dữ liệu từ URL đó, chẳng hạn như parmeters bằng cách sử dụng ký hiệu & thì có lẽ không phải là ý kiến ​​hay. Nói chung, bạn không muốn mô tả mơ hồ về những gì bạn đang cố gắng làm. Nếu bạn cần cụ thể thì đó là nơi $ _REQUEST không tốt, nếu bạn không cần cụ thể thì hãy sử dụng nó. Tôi sẽ nghĩ.


Bạn đang cố nói điều gì vậy? Bạn đang bối rối $_REQUESTvới $_SERVER['QUERY_STRING']?
Bỏ qua

0

Nếu bạn biết mình muốn dữ liệu gì, bạn nên yêu cầu rõ ràng. IMO, GET và POST là hai động vật khác nhau và tôi không thể nghĩ ra lý do chính đáng tại sao bạn cần kết hợp dữ liệu bài đăng và chuỗi truy vấn. Nếu ai đó có, tôi sẽ quan tâm.

Có thể thuận tiện khi sử dụng $ _REQUEST khi các tập lệnh của bạn có thể phản hồi GET hoặc POST theo cách tương tự. Mặc dù vậy, tôi sẽ tranh luận rằng đây phải là một trường hợp cực kỳ hiếm và trong hầu hết các trường hợp, hai hàm riêng biệt để xử lý hai khái niệm riêng biệt, hoặc ít nhất là kiểm tra phương pháp và chọn các biến chính xác, được ưu tiên hơn. Luồng chương trình thường dễ theo dõi hơn rất nhiều khi không cần thiết phải tham chiếu chéo nơi các biến có thể đến từ. Hãy tử tế với người phải duy trì mã của bạn trong thời gian 6 tháng. Đó có thể là bạn.

Ngoài các vấn đề bảo mật và WTF do cookie và biến môi trường gây ra trong biến REQUEST (đừng giúp tôi bắt đầu trên GLOBAL), hãy xem xét điều gì có thể xảy ra trong tương lai nếu PHP bắt đầu hỗ trợ các phương thức khác như PUT và DELETE. Mặc dù rất khó có khả năng những thứ này được hợp nhất vào siêu cầu thủ REQUEST, nhưng có thể chúng có thể được đưa vào tùy chọn trong cài đặt biến_đặt. Vì vậy, bạn thực sự không biết bất kỳ điều gì REQUEST nắm giữ và điều gì được ưu tiên, đặc biệt nếu mã của bạn được triển khai trên máy chủ của bên thứ ba.

POST có an toàn hơn GET không? Không hẳn. Tốt hơn nên sử dụng GET ở những nơi thực tế vì bạn có thể dễ dàng thấy trong nhật ký ứng dụng của mình đang bị khai thác như thế nào khi bị tấn công. POST tốt hơn cho các hoạt động ảnh hưởng đến trạng thái miền vì các trình thu thập thông tin thường không tuân theo chúng và các cơ chế tìm nạp dự đoán sẽ không xóa tất cả nội dung của bạn khi bạn đăng nhập vào CMS của mình. Tuy nhiên, câu hỏi không phải về giá trị của GET so với POST, mà là về cách người nhận nên xử lý dữ liệu đến và tại sao lại hợp nhất nó không tốt, vì vậy đây thực sự chỉ là một BTW.


0

Tôi nghĩ không có vấn đề gì $_REQUEST, nhưng chúng ta phải cẩn thận khi sử dụng nó vì nó là tập hợp các biến từ 3 nguồn (GPC).

Tôi đoán $_REQUESTvẫn có sẵn để làm cho các chương trình cũ tương thích với các phiên bản php mới, nhưng nếu chúng tôi bắt đầu các dự án mới (bao gồm cả thư viện mới) thì tôi nghĩ chúng tôi không nên sử dụng $_REQUESTnữa để làm cho các chương trình rõ ràng hơn. Chúng tôi thậm chí nên xem xét việc xóa việc sử dụng $_REQUESTvà thay thế nó bằng một hàm wrapper để làm cho chương trình nhẹ hơn, đặc biệt là trong việc xử lý dữ liệu văn bản đã gửi lớn, vì $_REQUESTchứa các bản sao của $_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: "Vì php 5.3, php.ini mặc định cho biết chỉ có dữ liệu GET và POST được đưa vào $_REQUEST. Hãy xem php.net/request_order. Tôi vừa vấp phải lỗi tương thích ngược này khi mong đợi dữ liệu cookie được đưa vào $_REQUESTvà tự hỏi tại sao nó lại không" không hoạt động! "

Chà ... vừa có một số tập lệnh của tôi ngừng hoạt động do nâng cấp lên PHP 5.3 . Thực hiện điều tương tự: giả sử rằng cookie sẽ được đặt khi sử dụng $_REQUESTbiến. Với việc nâng cấp chính xác đã ngừng hoạt động.

Bây giờ tôi gọi các giá trị cookie một cách riêng biệt bằng cách sử dụng $_COOKIE["Cookie_name"]...


-1

Vấn đề chính là nó chứa cookie, như những người khác đã nói.

Trong PHP 7, bạn có thể làm điều này:

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

Điều này tránh được sự cố cookie và tệ nhất là cung cấp cho bạn một mảng trống và tốt nhất là sự hợp nhất của $ _GET và $ _POST với ưu tiên sau. Nếu bạn không quá bận tâm với việc cho phép đưa các tham số vào URL thông qua chuỗi truy vấn, nó khá tiện lợi.


Những người chọn phản đối, vui lòng giải thích cho sự chỉnh sửa của tôi.
amh15

-2

Nó rất không an toàn. Ngoài ra, thật khó xử vì bạn không biết mình đang nhận được ĐĂNG hay NHẬN hoặc một yêu cầu khác. Bạn thực sự nên biết sự khác biệt giữa chúng khi thiết kế các ứng dụng của bạn. GET rất không an toàn vì nó được truyền trong URL và không phù hợp với hầu hết mọi thứ ngoài điều hướng trang. POST, mặc dù bản thân nó cũng không an toàn, cung cấp một cấp độ an toàn.


4
Không có sự khác biệt về độ an toàn giữa $ _POST và $ _GET, ngoài việc bạn không thể nhập yêu cầu POST vào thanh URL của trình duyệt. Tuy nhiên, chỉ mất 5 giây để đưa ra một yêu cầu cURL dòng lệnh bằng cách sử dụng POST.
zombat

3
@Zombat: Chúng tôi cần bắt đầu một số loại chiến dịch để thuyết phục mọi người rằng POST vốn dĩ không an toàn, hoặc thậm chí an toàn hơn GET. Bảo mật nằm ở cách bạn xử lý dữ liệu chứ không phải là những gì HTTP Verb được sử dụng để đưa nó đến đó.
Bỏ qua

@Dereleased - Tôi đề xuất một bức tranh hai tông màu mang tính biểu tượng của một đám mây với một số tia chớp để đại diện cho internet, với từ "CHANGE" bên dưới.
zombat

1
@GuyT: Đó là một quan điểm rất hạn hẹp. Nó không chỉ là về mức độ "an toàn" mà nó được bảo mật như thế nào. Tham số GET có thể hiển thị dưới dạng tự động hoàn thành trong url trình duyệt, thậm chí cả lịch sử trình duyệt. Ngoài ra, bảo mật không kết thúc với trình duyệt. Ví dụ: nhiều máy chủ ghi lại các url http, vì vậy bất kỳ thứ gì trong url sẽ được ghi lại chẳng hạn. Có tên người dùng / mật khẩu hiển thị trong nhật ký Có tạo ra sự khác biệt. Về mặt an toàn, luôn tránh chuyển thông tin nhạy cảm dưới dạng tham số GET.
stan

1
Cụ thể là các bản ghi truy cập Apache. Mọi url yêu cầu sẽ được ghi lại và BẤT CỨ AI có quyền truy cập vào nhật ký đều có thể thấy thông tin đăng nhập của bạn.
stan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.