PHP offers a convenience superglobal called $_REQUEST that coalesces input from a number of sources into one easy to use array. A common thought amongst PHP developers is that you should avoid the use of $_REQUEST -- but do you actually know why?

The prevailing misconception seems to be that having GET and POST variables mixed together is insecure. While this is true under some specific circumstances (see Cross-Site Request Forgeries for a weak example) -- it isn't the main reason why $_REQUEST is insecure. In fact, combining GET and POST data is often a very useful feature. In many cases you don't really care if a variable comes from GET or POST and so using $_REQUEST in those situations can help reduce the verbosity of your code while increasing flexibility.

The real problem is that COOKIE data is also mixed into $_REQUEST. The implications of this may not be readily apparent until you start thinking like a malicious user. Any cookie ever set on a users machine will always override any GET or POST data -- creating "sticky" variable data.

For instance, imagine if your application uses "action=" or "do=" switches to control page commands. If an attacker some how managed to set a cookie -- perhaps through some Javascript injection -- he could set a cookie named "action" and give it the value "logout." Any users that fell victim to the cookie set would never be able to use your application because "action" would be permanently set to "logout."

So to sum it up:

Question: Why is $_REQUEST insecure?
Answer: Because it combines COOKIE as well as GET and POST, and the COOKIE data always takes precedence -- creating the possibility for dangerous "sticky" variables.

Solutions

If you're already using PHP 5.3, then you can edit your php.ini and check the request_order variable -- make sure 'C' removed. This 'C' is removed by default, but if you use a shared host it might've been put back for backwards-compatibility. Make sure to check!

Otherwise, you can easily just create your own $_REQUEST array by merging $_GET and $_POST manually as part of your global initialization routines.

  1. $_REQUEST = array_merge($_GET, $_POST);

And finally, best practice is to abstract your input reading out (see Stop using superglobals!) so you can define yourself exactly how variables are read and from where.

7 Responses to “Why PHP’s $_REQUEST is dangerous”

  1. Spyros Says:

    Well, no..

    There is absolutely no security problem with using $_REQUEST. Getting input from cookie is the same as getting input from get or post.

    If $_REQUEST was indeed a security flaw in PHP, it would have been removed.

  2. Christopher Nadeau Says:

    Did you not read the article at all?

    The fact that cookie data takes *precedence* in $_REQUEST over the others is the dangerous part. Indeed, even if it was last, it would still be dangerous for the simple fact that a specific value would could always be set.

    No one wants to remove $_REQUEST itself from PHP. Only cookie data should be removed. In PHP 5.3 we have the 'request_order' php.ini setting which has cookies disabled by default:

    request_order
    Note that the default distribution php.ini files does not contain the 'C' for cookies, due to security concerns.

  3. Toby Says:

    Cheers for the explanation, my php.ini was clean but it is a good thing to be looking out for.

    I have seen a lot of code floating about that would check against $_REQUEST using if(isset($_REQUEST['wibble'])), just calling the script with script.php?wibble=y will trigger this even if it is a $_POST variable that should be being checked.

  4. Useful Security Pages | Toby's Development Blog Says:

    [...] Why $_REQUEST is dangerous [...]

  5. php mail() validation Says:

    [...] $_COOKIE as usual. I found a nice text explaining why $_REQUEST has a problem, so read for example Why PHP’s $_REQUEST is dangerous - Devlog and see what the problem really is, and how you can avoid the problem. [...]

  6. Jeremy Simkins Says:

    I make it a point to never use $_REQUEST. Even studying for the ZCE explains that $_REQUEST is a major security risk. Spyros, you are completely wrong.

    Thanks for the article, very useful information. Let's hope people learn from this...

  7. Christian Sciberras Says:

    Jeremy did you even read the article? Spyros is wrong, but so are you.

    The author specifically said that $_REQUEST is only insecure because of $_COOKIE in request_order, which for your information, has been disabled for quite some time.

    So to sum it up, $_REQUEST, is a very useful feature which is best used with newer versions of PHP.

    There are no other ulterior "major security risks".

Leave a Reply