7 ms·
I don't get why people keep harping on super globals are being inherently bad. The variables are there. You can use them or ignore them. A variable definition h
by Akujin 10y ago
I don't get why people keep harping on super globals are being inherently bad. The variables are there. You can use them or ignore them. A variable definition harms you in no way other than a tiny bit of memory usage which is capped by the HTTP limit on POST and GET limits anyway. What? You think you're gonna get hacked because $_POST['ihaxyou'] is set to 'w00ts'?
No one does this anymore:
mysql_query("SELECT * FROM `table` WHERE `id`=".$_POST['ID']);
There's absolutely NOTHING wrong with having $_POST['whatever'] inside a controller as long as you're doing proper checks.
Are you expecting it to be an integer? Easy
if(!ctype_digit($_POST['ID'])) {
// throw exception here
}
Contrary to the hive mind you don't need some special encapsulation class to pull your post and get variables.
HHVM does not in any way solve this issue. You still have to write proper validation into your code or you'll get hacked. What's with people expecting frameworks to do everything for them these days?
- wdewind 10y ago> Contrary to the hive mind you don't need some special encapsulation class to pull your post and get variables. The hive mind is like that for a reason. Making it easy to do the right thing and wrong to do the wrong thing has massive effects, I'd argue the magnitude of which scale exponentially with the growth of an engineering team. Really really talented engineers make mistakes all the time. To the extent that we can systematically limit those with little to no downside we absolutely should, especially when it comes to security.
- Akujin 10y agoI think people are also confusing an old issue from PHP 4.x where if you had $_POST['somevar'] it would actually have an alias automatically set as $somevar in the global userspace. This was turned off by default a long time ago and is the main real security issue when it comes to super globals. $_POST and $_GET are just the normal way to access POST and GET vars. There's nothing inherently insecure about it.
- kyriakos 10y agoExactly, this is where the real problem was and thankfully it was fixed. An attacker could insert any variable in a script just by adding it to the URLs additionally the PHP configuration could change variable order the variables from different sources were given so a script essentially didn't know where it was getting the information from. On the other hand the super globals are just a utility making things easier for the developer, they don't directly make code insecure.
- nilliams 10y agoI don't think people are confusing those things at all. The comment you're replying to is quite literally saying that using $_POST['somevar'] is too easy.
- mastre_ 10y ago> I don't think people are confusing those things at all. The comment you're replying to is quite literally saying that using $_POST['somevar'] is too easy. Are you guys, then, saying that $_POST['id'], by itself, is less secure than a getPostVar('id') would be, by itself?
- unabst 10y agoIn all seriousness, shouldn't all the frameworks just have some validation built in? Being that this is such a "global" WTF problem. I would love to be able to say ini_set('sanitize_rest', true) and deal with errors that might result from that knowing at least the strings are safe. Or have functions like sanitize_string($str) and have the documentation encourage it everywhere. I mean, aren't we all just implementing those on our own anyway? I know that obviously there are already functions for type checks etc, but the idea is to make it even easier, more obvious, and functions directly targeting the problem, even if they are mere aliases. When a mistake is easy, the solution should be made easier.
- kijin 10y agoPHP has already tried automatic sanitization with magic_quotes_gpc, and the results were far from secure. It is not possible to have a single sanitize() function that renders a string safe for every possible context, and to try to provide one results in nothing but complacency and false sense of security. Escaping for SQL is different from escaping for HTML, and even if you escaped a string for both, some idiot is going to echo it inside an inline script or a CSS attribute. Sanitize for all of them, and you begin to seriously mangle those strings. Oh, and it might still be ineffective against directory traversal. I've seen plenty of PHP users who think they're clever because they wrote a function that applies every single escaping function in a row, not realizing them some of them undo one another's work. Selectively unescaping after the fact is even more fun. The only thing I can think of that could render a string absolutely safe in every context is intval(), but then you don't have a string anymore, and I suspect that even that can be abused with unexpected zeroes and negative values.
- Goopplesoft 10y ago> What's with people expecting frameworks to do everything for them these days? I don't think that's the expectation. PHPs reputation seems to surround the fact that it tends to be (or was) the first language amateur coders dabbled with. That crowd is especially susceptible (at least before mysqli, etc) to making mistakes that amount to serious security vulnerabilities. Historically, these seemingly benign things that can only go bad if you dont know better, do go bad [1]. It seems that this lead rampant conflation of whether php is a bad language and whether php made it easier to do things in an unsafe way. Frameworks that create safer environments for devs (especially newer ones) are certainly a good thing and the good frameworks often get out of your way when you need them to. [1] https://github.com/search?p=3&q=extension:php+mysql_query+%24_GET&ref=searchresults&type=Code https://github.com/search?p=3&q=extension:php+mysql_query+%2...
- SomeCallMeTim 10y ago>PHPs reputation seems to surround the fact that it tends to be (or was) the first language amateur coders dabbled with. That's certainly part of it. JavaScript suffers the same hate today -- amateur and junior developers produce thousands of lines of crap per year, and people blame it on the language. But PHP itself is just a mess. I'm an experience developer (about 30 years at this point), and about 12 years ago I decided to do a volunteer project for a nonprofit in PHP. Finished the project and the nonprofit used it for at least 10 years -- they may still be using it for all I know. Never. Again. I can't stand PHP and I will avoid its language and ecosystem like the plague. Even if they've fixed some of the problems in the core language and added types, the "standard" libraries were a random pile of mismatched garbage where the mysql_xxxx functions could have parameter signatures in different orders than the pg_xxxx versions. Maybe they've fixed that as well, but they'd have to break backward compatibility in pretty awkward ways to achieve that. I don't even remember all the other things that tortured me, but it wasn't fun. And it's not asynchronous. There's not even a good reason to use a synchronous language for web development today. Not to mention the ease of running NodeJS code in a debugger, or running tests in a browser and debugging it there... I'm using TypeScript and Go for all my web related code moving forward. Something better comes along, and I'll consider it. But PHP was just a nightmare. (Elm on client? Maybe, under the right circumstances?)
- developer2 10y ago> Are you expecting it to be an integer? Easy > if(!ctype_digit($_POST['ID'])) { // throw exception here } ctype_digit is broken. Try passing integer values. ctype_digit(50) === true, but ctype_digit(100) === false. And "0000001" passes as true, which most people in the majority of scenarios would prefer not to pass. I can't remember what the even-worse-bug is with ctype_digit is, but even if you cast the value to string [ex: ctype_digit((string)$var))], there is some value that still passes for true when it shouldn't - do not use ctype_digit. is_numeric() is also unusable for validation [is_numeric("123e4") === true]. is_int() is a strict type-check so can't solely be used to validate request variables which are always strings (...or arrays, more below). The only correct ways to verify that a variable contains either a valid numeric string or integer is by comparing type, and then using a regex or a double string-then-int cast. ex: unsigned database ids: if ((is_int($var) || is_string($var)) && preg_match('/^[1-9]\d*\z/', $var)) { // definitely an int > 0 } ex: signed integer: if (is_int($var) || (is_string($var) && (string)(int)$var === $var)) { // valid int (including negative values) } Frankly, developers who don't understand how request variables are handled in PHP have zero chance of properly validating input. Find any site/app written in php, even if built on any of the major frameworks. You can instantly break 30-50% of them by passing an array where a string is expected. Find an app that takes "?query=hello+world". Instead pass in "?query[]=hello+world". Want an example? Log in to Facebook, then visit this search page[1]. Look at the query string and then what was searched for - and the contents of the search box. Bam, even Facebook gets it wrong! Same thing with Symfony's search[2]. Or Packagist (composer's package manager repository)[3]. More seriously at Yii[4], which exposes an internal error to users as they try to string-trim an array ("Error - trim() expects parameter 1 to be string, array given"). Most developers - including many seniors who have been exclusively coding in php for years - have no clue. You will either cause a 500 Internal Server Error, or your input array will result in an output string of "Array" if they typecast your array to the string they expected. Even the major frameworks, when you pull user-submitted values, simply passthrough the value submitted. Your app expects a string (or a string that contains a numeric value), and instead any user who knows the "[]" syntax can pass in an array. Really reflect on this fact. Most applications start handling a submitted array value as if it's a string. The bugs this produces are astronomical in some cases. If you think your framework protects you, think again. The frameworks' request objects also do not have strict type checking. The same goes for their form and model validation classes; if you're using the built-in "integer" or "numeric" validators, you're probably doing things wrong. It's a nightmare. You could try to blame PHP, but really it's the developers - including the developers of every major well-known framework I've ever touched - that have absolutely no clue. Related tangent: comparing password and password confirmation fields. Many developers do if ($password == $passwordConfirm) {}. In PHP 5.x, "10" == "0xA" (so type "10" in password field and "0xA" in the confirmation field, and it passes validation). This changed in PHP 7 though. There are only two correct ways to verify that two strings are exact: $password === $passwordConfirm (triple equals), or strcmp($password, $passwordConfirm) === 0. [1] https://www.facebook.com/search/top/?q[]=hello https://www.facebook.com/search/top/?q[]=hello [2] https://symfony.com/search?q[]=hello https://symfony.com/search?q[]=hello [3] https://packagist.org/search/?q[]=hello https://packagist.org/search/?q[]=hello [4] http://www.yiiframework.com/search/?q[]=hello http://www.yiiframework.com/search/?q[]=hello
- babyrainbow 10y ago> The variables are there. You can use them or ignore them... Ever worked in a team?
- phatbyte 10y agoDoesn't PHP 7 support type declarations? eg: function foo(int $number) { ... }
- Aaargh20318 10y ago> There's absolutely NOTHING wrong with having $_POST['whatever'] inside a controller as long as you're doing proper checks. The last part is why this is a problem. The truth is that programming is simply too difficult a task for human beings. Software is so complicated with so many moving parts that it is impossible for anyone to understand all the details of even the simplest piece of code. This is why we have operating systems, programming languages, and frameworks. Or more generally: this is why we have abstractions and tools: to make it possible for humans to actually write somewhat functional software. This is also why you not only want languages, frameworks and tools that let you do the right thing; you want them to prevent you from doing the wrong thing. You want to reduce the number of things you have to think about to the absolute minimum, simply because no one is smart enough to fully understand everything that's going on. That is why you want things like strongly typed languages. Sure, you can make something that works and is safe, if you make no mistakes. The point is that we want to take the human ability to make mistakes out of the equation as much as possible. Sometimes it is inevitable because of what a language, framework or tool is used for. In the case of PHP there are a lot of ways to shoot yourself in the foot that do not need to exist in a high-level language such as PHP, and that is the reason why PHP sucks and is a bad idea. It is way more fragile than it has a need to be.
- wwweston 10y ago> The last part is why this is a problem. $_POST isn't the problem. The scope of the variable isn't the problem. You've realized this, too, and that's why you're shifting the argument to one about typing instead of superglobals-are-bad (typing and scope are obviously independent features). > You want to reduce the number of things you have to think about to the absolute minimum The net effect of type systems seems to actually be to force you to think about a larger number of things very very carefully. The only thing that ends up being reduced is having to think about having to think about them.
- berdario 10y ago> typing and scope are obviously independent features You might want to read about effect systems http://rtpg.co/2016/07/20/supercharged-types.html http://rtpg.co/2016/07/20/supercharged-types.html (it might not be the best blog post on the subject theory, but I think it's a nice practical example)
- krapp 10y ago>No one does this anymore: >mysql_query("SELECT * FROM `table` WHERE `id`=".$_POST['ID']); People do still write PHP like this, because they aren't even aware that SQL injection is a thing. I've seen it in code written relatively recently. >Are you expecting it to be an integer? Easy >if(!ctype_digit($_POST['ID'])) { // throw exception here } You forgot to check that the index "ID" exists first, that will throw a warning if it doesn't. >Contrary to the hive mind you don't need some special encapsulation class to pull your post and get variables. You don't need it,but encapsulation is still useful. You may want to use some source other than the superglobals, maybe for testing. >What's with people expecting frameworks to do everything for them these days? Frameworks are supposed to come with proper data validation out of the box - if they don't, they're bad frameworks.