I've come across a couple of popular PHP-related answers recently that suggested using the superglobal $_REQUEST
, which I think of as code smell, because it reminds me of register_globals
.
Can you provide a good explanation/evidence of why $_REQUEST
is bad practice? I'll throw out a couple of examples I've dug up, and would love more information/perspective on both theoretical attack vectors and real-world exploits, as well as suggestions of reasonable steps the sysadmin can take to reduce risk (short of rewriting the app ... or, do we need to go to management and insist on a rewrite?).
Example vulnerabilities: Default GPC
array merge-order means that COOKIE values override GET and POST, so $_REQUEST
can be used for XSS and HTTP attacks. PHP lets cookie vars overwrite the superglobal arrays. First 10 slides of this talk give examples (whole talk is great). phpMyAdmin exploit example of CSRF attack.
Example countermeasures: Reconfigure $_REQUEST
array merge-order from GPC
to CGP
so GET/POST overwrite COOKIE, not the other way around. Use Suhosin to block overwrite of superglobals.
(Also, wouldn't be asking if I thought my question was a dupe, but happily the overwhelming SO answer to "When and why should $_REQUEST be used instead of $_GET / $_POST / $_COOKIE?" was "Never.")
Just treat it as it is: a method to get data from the user. It has to be sanitised and validated, so why should you care if it came in the form of a POST, a GET or a cookie? They all come from the user, so saying 'they can be spoofed!' is superfluous.
$_REQUEST is a evil as $_GET, $_POST and $_COOKIE. While i think there are valid scenarios for using $_REQUEST but there is one good reason not using $_REQUEST and label it as "bad practice".
The main reason using $_REQUEST is that parameter can get transferred in $_POST or $_GET. By accessing $_REQUEST you don't have to check both $_GET and $_POST it the value is set. The problem is that the ini setting gpc_order can change the behavior how $_REQUEST is build. This setting may differ from server to server and you script may change the behavior.
$_REQUEST
is problematic because it ignores the difference between URL ($_GET
) and request body ($_POST
). A HTTP-GET request should be without side-effects, while a HTTP-POST may have side-effects and thus can't be cached. Throwing these quite different data sources into one bucket, calls for applications that are un-REST-ful, which is to say bad applications.
Its vulnerable to anything passed on the URL. Thus if a form contained a hidden field with the "userid" that was submitted with the form, although in theory the user can't edit it, there is nothing stopping them change the value if keen enough.
If you just want to get the value off the request, thats fine, but you need to be aware that it may very well be spoofed, so you need to act accordingly, and certainly not use it for secure param/value data.