which one to use and why ?
Moderator: General Moderators
Answering LIFO:
@Oren:
). I repeat:
What feyd "sums up" is an answer to Everah's concerns about variable overwriting with $_REQUEST, not to the security or insecurity of knowing "where your data comes from"
Thanks for using "probably" though, or I'd have accused you of "ad hominem" arguments
@Everah: I know of the argument and I find it flawed.
In order for this to work, you need a XSS vulnerability on the site, which will have way more severe consequencies than just being able to set a cookie. What setting a cookie would achieve is a fixation of some parameter, which would at most cause a mild DoS for this site (by for example taking the user to the same article id, no matter which article link he clicks on).
@Jcart: I don't need a request object, I have my nice function, thankyouverymuch
The trouble with more code is not only that it takes longer to execute, but longer to write and read. Also, this concerns the first part of my argument, about the "pros" of using $_REQUEST, while the discussion here is about the second part, that there are no "cons" (my thesis, which you are invited to disprove).
@Kieran: We shall prevail!
(But let's not go into the usability "pros", let's hear arguments about the supposed security "cons".)
@Everah about
I know what superglobals are, thankyouverymuch 
On a second glance, you will notice though that I don't pass the superglobals themselves, but only the variable I need:
This is done because of two reasons:
1. So I can check if the var is set
2. So I can use the same function for all ocasions that I need a var converted (I have similar functions not only for ints, but for strings and enums and arrays thereof, and the functions themselves can optionally handle additional restrictions, for example ints within a certain boundary etc. etc., in short - it's very useful to me)
I fail to see how
is simpler than
, or if you insist
though 
(But let's not go into the usability "pros", let's hear arguments about the supposed security "cons".)
@Oren:
Bah, cowdung (yay, I beat the smurf filterand if you don't even know where your data comes from, then you probably won't handle (validate, filter...) it properly.
"know where your data comes from" is a problem only if one mistakes user input for trusted data. I don't think $_REQUEST looks more trusted than $_GET or $_POST, do you?Mordred wrote:True, $_REQUEST may also contain data from other sources, but I usually don't care, and treat them equally (i.e. any unsecure handling I'd do with $_REQUEST, I would have also done with $_GET and $_POST).
What feyd "sums up" is an answer to Everah's concerns about variable overwriting with $_REQUEST, not to the security or insecurity of knowing "where your data comes from"
Thanks for using "probably" though, or I'd have accused you of "ad hominem" arguments
@Everah: I know of the argument and I find it flawed.
In order for this to work, you need a XSS vulnerability on the site, which will have way more severe consequencies than just being able to set a cookie. What setting a cookie would achieve is a fixation of some parameter, which would at most cause a mild DoS for this site (by for example taking the user to the same article id, no matter which article link he clicks on).
@Jcart: I don't need a request object, I have my nice function, thankyouverymuch
@Kieran: We shall prevail!
I do, and often, because of the way I handle situations. Some things, like bookmarks and redirects work only with _GET, while (large) forms require using _POST. Because I use reusable encapsulated (/winks at Jcart) code, $_REQUEST is exactly what I need to make it transparently work in both situations.although I rarely have an instance when I don't know the request method going in.
(But let's not go into the usability "pros", let's hear arguments about the supposed security "cons".)
@Everah about
Ouch, am I so inexperienced in your eyes?GET and POST are superglobal, so you really don't need to pass them to the function.
On a second glance, you will notice though that I don't pass the superglobals themselves, but only the variable I need:
Code: Select all
$nId = GetInt($_REQUEST['id'], 0); //not $_REQUEST, but $_REQUEST['id']1. So I can check if the var is set
2. So I can use the same function for all ocasions that I need a var converted (I have similar functions not only for ints, but for strings and enums and arrays thereof, and the functions themselves can optionally handle additional restrictions, for example ints within a certain boundary etc. etc., in short - it's very useful to me)
I fail to see how
Code: Select all
<?php
$nId = 0;
if (isset($_POST['id']) || isset($_GET['id'])) {
$nId = isset($_POST['id']) ? intval($_POST['id']) : intval($_GET['id']);
}
?>Code: Select all
$nId = GetInt($_REQUEST['id'], 0);Code: Select all
$nId = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;(But let's not go into the usability "pros", let's hear arguments about the supposed security "cons".)
Using $_GET, $_POST and $_COOKIE instead of $_REQUEST is (in a way) type hinting, just like class type hinting. In more mature languages like C and Java, you can't choose - you have to declare your variables beforehand including their type (which indicates their max size too for primitive types). In Java (maybe with C too, I don't know) when you pass an instance of a class, you must declare the type of this class too and you also declare the type of the class when you initiate it:
I guess there are good reasons for doing it this way, and maybe PHP will adapt this one day and will be a little bit more strict (I'm sick of PHP considered a language that every noob can use and create crappy crappy crappy applications with
).
Code: Select all
my_class var_to_hold_the_instance = new my_class();- stereofrog
- Forum Contributor
- Posts: 386
- Joined: Mon Dec 04, 2006 6:10 am
I think the others already said enough, so let me be short. You should always check where exactly the data comes from and if you do so, REQUEST is at best useless.Mordred wrote: I would gladly revise my oppinion if I see a viable scenario when using $_REQUEST brings any harm, so I leave the burden of proof to you guys, Everah, onion2k, stereofrog.
And I'm with Jcart here: in OOP world using superglobals is strictly limited to a Request class. In my scripts there's usually one single line with a reference to $_GET or $_POST.
Code: Select all
class Request {
function __construct() {
$this->is_post = !strcasecmp(@$_SERVER['REQUEST_METHOD'], 'POST');
$this->params = ($this->is_post) ? $_POST : $_GET;
}
function param($name) {
return isset($this->params[$name]) ? $this->params[$name] : null;
}
}
# the rest of script uses:
$rq = new Request();
$blah = $rq->param('blah');Mordred wrote:I fail to see howis simpler thanCode: Select all
<?php $nId = 0; if (isset($_POST['id']) || isset($_GET['id'])) { $nId = isset($_POST['id']) ? intval($_POST['id']) : intval($_GET['id']); } ?>, or if you insistCode: Select all
$nId = GetInt($_REQUEST['id'], 0);thoughCode: Select all
$nId = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
(But let's not go into the usability "pros", let's hear arguments about the supposed security "cons".)
Code: Select all
$nId = isset($_POST['id']) ? intval($_POST['id']) : intval($_GET['id']); Code: Select all
$nId = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;At the end of the day you're right, there's no good security reason to trust GET and POST more than REQUEST. You shouldn't trust any incoming data, so the fact it's posted or in the URL makes no difference. The reason I use them is simply because I want my code to work the same way everywhere regardless of the php.ini settings.
Now that really sums it uponion2k wrote:At the end of the day you're right, there's no good security reason to trust GET and POST more than REQUEST. You shouldn't trust any incoming data, so the fact it's posted or in the URL makes no difference. The reason I use them is simply because I want my code to work the same way everywhere regardless of the php.ini settings.
I agree (not only now - from the beginning) that as long as you know what you are doing, you will be safe, but I still believe this is poor design and all the things I've said are still valid - at least in my opinion.
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
In reading the arguments a few are horribly flawed. Let's be clear that GET and POST are not the same thing. Pretending they are in any way, shape or form, is self-delusion. You should NEVER use GET data when the context is expected to be POST. It's a very common practice - and very very wrong.I would gladly revise my oppinion if I see a viable scenario when using $_REQUEST brings any harm, so I leave the burden of proof to you guys, Everah, onion2k, stereofrog.
The root problem is that using $_REQUEST introduces a security issue without exception - HTTP Request Spoofing. This is because any GET request will be able to replicate any POST request. This leads to the horror of horrors - Cross Site Request Forgeries. A CSRF attack relies on a web application being unable to differentiate between GET and POST attacks. It also relies on the web application trusting the user (post-authentication this is rarely avoidable and is represented at the most basic level by the Session Cookie which is carried by ALL - regardless of source - requests to the cookie's domain). A simple example is easy to follow.
User A logins into Acme Pet Shop's Online Store. Acme supplies an online form to allow a user perform an action such as buying Parrots which after authentication require no further input or confirmation. User A has no intention of using that form. Shortly thereafter, User A receives a cute email in their inbox from Acme Pet Shop (aka Spammers United in disguise) - the account details for User A were lost in a datacenter fire, and they've kindly supplied a link to input this information again. User A clicks the link - their cookie for Acme Pet Shop's domain is still valid so they are still authenticated. User A finds him/herself staring at a receipt for the purchase of 600 Parrots. User A is not very happy and contemplates shooting the monitor.
Acme Pet Shop just got stung for validating a purchase order using $_REQUEST without realising anyone outside his site is free to create custom GET url's (hyperlinks) with the same data, which if clicked by User A represent a forged form request (i.e. a CSRF attack).
Could people now please stop promoting $_REQUEST. It's not nice, it's not friendly, it's certainly NOT useful except in a teeny tiny set of circumstances where a specific subset of data represent nothing more than a resource request (i.e. a GET buried in a POST request action holding path information).
Please help stop this evil creature from spreading!
- RobertGonzalez
- Site Administrator
- Posts: 14293
- Joined: Tue Sep 09, 2003 6:04 pm
- Location: Fremont, CA, USA
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
As you mention, a POST request can also be forged with another POST request from an offsite form - very good point to make since CSRF is a bigger topic than just $_REQUEST
. It's a slightly different forgery type, but with the exact same results. Difference here is that it ignores GET, and uses valid POST input data from an offsite or custom edited form. This has a few different solutions than in my example, e.g. proper confirmations over actions, re-authentication for important actions, form single-use tokens to force usage of correct forms, etc.
In general, any request can be forged very easily - those where GET is treated the same as POST are just more obvious in explaining why $_REQUEST is evil
.
In general, any request can be forged very easily - those where GET is treated the same as POST are just more obvious in explaining why $_REQUEST is evil
Maugrim, I am relieved that you refuted your previous post, so that I won't have to teach basics to old guns like yourself and the next posters 
I think that concludes the dispute of $_REQUEST's supposed insecurity, and I will now proceed to the other point, that (to oversimplify) $_REQUEST leads to smelly code.
On rereading the thread, we have roughly these claims:
1. $_REQUEST relies on php.ini setting for the order or vars, which is bad (1st part is obviously true
)
2. Input from the request should be handled by a class, as the OOP gods command us
3. "Type hinting" (?) Okay - source hinting.
4. Poor design to have variables with the same name from two different sources
5. There is never a good need to use $_REQUEST
I'll add one more:
6. $_GET and $_POST have different semantics (as per the HTTP RFCs), so using $_REQUEST violates the standart (and is an abomination unto Nuggan)
I will try to answer them tomorrow, as it has become too late. Do add more to the claims/arguments in case I've omitted something.
Oh, and thanks for participating in this discussion, I am a great believer in the scientific principle, and this is exactly what we are doing in this thread - science!
I think that concludes the dispute of $_REQUEST's supposed insecurity, and I will now proceed to the other point, that (to oversimplify) $_REQUEST leads to smelly code.
On rereading the thread, we have roughly these claims:
1. $_REQUEST relies on php.ini setting for the order or vars, which is bad (1st part is obviously true
2. Input from the request should be handled by a class, as the OOP gods command us
3. "Type hinting" (?) Okay - source hinting.
4. Poor design to have variables with the same name from two different sources
5. There is never a good need to use $_REQUEST
I'll add one more:
6. $_GET and $_POST have different semantics (as per the HTTP RFCs), so using $_REQUEST violates the standart (and is an abomination unto Nuggan)
I will try to answer them tomorrow, as it has become too late. Do add more to the claims/arguments in case I've omitted something.
Oh, and thanks for participating in this discussion, I am a great believer in the scientific principle, and this is exactly what we are doing in this thread - science!
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
Elaborated, not refuted...
.
My original post clearly states that $_REQUEST when used in preference to $_GET/$_POST is a security vector. I just failed to explain CSRF has numerous such vectors an attacker can attempt to exploit. This is hardly a debatable conclusion - there are numerous examples of real world cases in PHP where $_REQUEST preferences contributed to CSRF exploits. PHP applications
The second post added that spoofing was not solely a REQUEST->POST issue, but extended to POST->POST using forged forms. However the solution for this case is different. Both variations are discrete issues, since both have a slightly different methodology. One uses a hyperlink, the other a forged form. Both can lead to CSRF, but have different solutions which are not mitigated by input validation.
I could have easily added others. Javascript (due to AJAX) has seem a little more attention recently since XMLHttpRequest can pass along POST or GET requests from a user without all that annoying user initiation required.
My original post clearly states that $_REQUEST when used in preference to $_GET/$_POST is a security vector. I just failed to explain CSRF has numerous such vectors an attacker can attempt to exploit. This is hardly a debatable conclusion - there are numerous examples of real world cases in PHP where $_REQUEST preferences contributed to CSRF exploits. PHP applications
The second post added that spoofing was not solely a REQUEST->POST issue, but extended to POST->POST using forged forms. However the solution for this case is different. Both variations are discrete issues, since both have a slightly different methodology. One uses a hyperlink, the other a forged form. Both can lead to CSRF, but have different solutions which are not mitigated by input validation.
I could have easily added others. Javascript (due to AJAX) has seem a little more attention recently since XMLHttpRequest can pass along POST or GET requests from a user without all that annoying user initiation required.