Re: Security Issues

From: Date: Mon, 30 Jul 2001 08:00:47 +0000
Subject: Re: Security Issues
References: 1 2 3  Groups: php.dev 
Request: Send a blank email to php-dev+get-61440@lists.php.net to get a copy of this message
UNSUBSCRIBE ME PLEASE!!!!!!!!!!!!!! Zeev Suraski schrieb: > At 06:01 28/07/2001, Phil Driscoll wrote: > >Apologies in advance to Zeev for arguing on this one, but be assured I firmly > >believe that your solution would be to the detriment of PHP and a better > >solution is possible :) > > > >On Saturday 28 July 2001 12:44, Zeev Suraski wrote: > > > > > > NO!! :) Saying people would stop using PHP (or won't get started) because > > > of this change is a gross exaggeration. IMHO, the one and only issue at > > > hand here is downwards compatibility, and not usability or ease of use, not > > > even a bit. > > > >Sorry Zeev - the answer is YES. I and no doubt thousands of others will turn > >register_globals on because it gives much more readable code, much less > >typing and does not IMHO add one jot to the security of my applications. > > I have no doubt that thousands would turn it back on. I can't do anything > about it, and as I said numerous times in numerous metaphors, I'm quite > alright with that. I also have no doubt that the alternative ways we'll > provide would result in a firm 'NO', and definitely not a 'YES'. I > can't > imagine a single person stopping to use PHP because the default changed > (why the heck not just change it back, isn't it easier than learning a > whole new alternative platform?). I also can't imagine people avoiding PHP > because variables are accessed using $_FORM['foo'], instead of > $foo. People are not *THAT* dumb or lazy. Discussing this issue in the > OSCon, Rasmus claimed that right now he can teach PHP to a monkey in 3 > hours, and he wouldn't want to be limited only to smart Gorillas in the > future. I firmly believe that if a monkey can figure out $foo, > $_FORM['foo'] is not going to be the showstopper. > > > > That's not going to find half, or a quarter, or whatever of the problems, > > > since PHP has tools to cleanly handle undefined variables - namely isset() > > > and empty(). They, or at least isset(), are quite popular. > > > >I always use something like: > > > >if(!isset($Thing) /*and possibly some range checking*/)) > > $Thing="sensible default"; > > > >In no way is > > > >if(!isset(_GET['Thing']) /*and possibly some range checking*/)) > >{ > > $Thing="sensible default"; > >} > >else > >{ > > $Thing=(_GET['Thing']); > >} > > > >any more secure (nor would it be if I wrote "sensible default" back to _GET. > > Any programming language gives you a long enough rope to hang you. I argue > that PHP gives you a hanging loop and places it on your neck, leaving you > only a couple of steps away from breaking it. Your example clearly states > a piece of code where at the end, you have $Thing defined. In the 2nd > example, it's clear beyond a reasonable doubt that it may come from user > input, because it's written explicitly. However, if we turn $Thing back to > $Auth, and add it in context: > > /* part 1 */ > if (sth) { > $Auth = 1; > } > /* end part 1 */ > ...a few dozen lines of code... > /* part 2 */ > if (isset($Auth)) { > ... do something ... > } else { > ... do something else ... > } > /* end of part 2 */ > > In this case, having written part 1, it's not clear *at all* that Auth may > be coming from user input. Should it be? Yeah. But as I've been > repeating myself again and again in the last few days, as the advisory > said, effectively it is NOT. Even Brian, which opposes the > register_globals=off thing, found quirks in his code that he did not > anticipate because of the state of mind PHP puts you in. In part 2, you're > completely vulnerable to attacks. If part 1 had to be explicit, the danger > would have been a hell of a lot clearer. > So yes, you can hang yourself still, you're just a few feet farther away > from the hanging loop now, and it comes with a warning sign. > > >Anyway, to check my sanity i have reread the security advisory which I first > >read on the day it was published, and I am even more conviced now that > >register globals=off has the tiniest of effects for gpc variables wheras > >E_NOTICE has a massive effect. > > > >Here are the examples from the advisory: > > > >------------------ > > <?php > > if ($pass === "hello") //= corrected to === > > $auth = 1; > > ... > > if ($auth == 1) > > echo "some important information"; > > ?> > > > >replace $pass with _GET['pass'] and the code is > >equally insecure. Turn E_NOTICE on and the novice programmer will get a > >warning message for the unset $pass. > > No it is not. $auth can no longer come from user input, so it's > safer. $pass being unset is not much of a problem. > > >------------------ > > <?php > > if (!($fd = fopen("$filename", "r")) > > echo("Could not open file: $filename<BR>\n"); > > ?> > > > >replace $filename with _GET['filename'] and this lunatic piece of code > >remains a lunatic piece of code. If $filename is not meant to be coming from > >the outside world then with E_NOTICE on there would be a warning message for > >the unset filename. > > How is that security? And what if I pass filename=""? > > >------------------ > > <?php > > include($libdir . "/languages.php"); > > ?> > >Ok, with register_globals=off then $libdir could not be directly overwritten > >from outside (unless there was some code which made that happen) however > >E_NOTICE would generate a warning for an unset $libdir > > Why would libdir be unset? The issue here is that under some > circumstances, you can override variables. Different things happen in > different paths of your logic, so testing is a nightmare if you just rely > on the E_NOTICE feature. > > >------------------ > >File upload. > >If you don't use the new functions you are potentially stuffed with register > >globals on or off. > > Having written the new functions, I don't recall why you'd be stuffed with > register_globals=off. As far as I recall, the entire problem was a direct > result of register_globals=on, and not enough track_vars functionality > available at the time to write secure code. It was a while ago, so I could > be wrong, though. > > >As an aside - we could have a php.ini directive which could 'break' code > >which did not use the new functions - if we save an uploaded file with one > >name, but set the $userfile_name to something else, and only rename the > >original to $userfile_name after a call to is_uploaded_file or > >move_uploaded_file. > >------------------ > > <?php > > if (file_exists($theme)) // Checks the file exists on the local system (no > >remote files) > > include("$theme"); > > ?> > > > >This seems to be the same as the fopen($filename... example above. > > Again, I'm not exactly sure what the security risk here is, but I just woke > up :) > > >------------------ > >In libdir/loadlanguage.php: > > <?php > > ... > > > > include("$langDir/$userLang"); > > ?> > > > >include files called out of context. The solution is to configure your web > >server, or put the include files outside the webroot so that they cannot be > >run out of context. > > > >In this example, typically $langdir should have been set inside the > >application or a configuration file, but $userLang will typically have come > >from the user either with this request, or previously and stored in a > >database in the users profile. > > > >So under the register_globals = off scheme, we would often end up with > >something along the lines of: > > > ><?php > > ... > > > > include("$langDir/_GET['userLang']"); > > ?> > > > >where $langDir is unset. We can all see how secure that is :) > > But that's running towards the hanging loop from a mile away, wrapping it > quickly around your neck and pushing the lever. You can't do much about > suicidals :) > > >------------------ > >Session files. > > > >I am happy to concede that there should be a php.imi directive which stops > >variables which can more or less be trusted, such as env and session from > >entering the global namespace, so that if you want to read them you have to > >look in the correct place. > > Cool :) > > >------------------ > > > >In conclusion I would urge those who want to set register_globals=off to > >reconsider. A better solution is required. The better solution involves some, > >all, or more of: > >E_WARNING > >more granularity to the register_globals directive > >the file upload changes I mentioned as an aside > > I think your examples were very good reasons why in fact register_globals > should be set to off by default. I think that in the state of mind you're > in, you're no really accounting for the state of mind that most PHP > developers are, and thus, making a mistake by assuming that turning > register_globals off is not going to have a far reaching security improving > effect. Even if people just go over their code and explicitly declare > which variables are coming from the user space, even that alone is going to > help them audit their apps to a much higher level of security than it is today. > > Zeev > > -- > PHP Development Mailing List <http://www.php.net/> > To unsubscribe, e-mail: php-dev-unsubscribe@lists.php.net > For additional commands, e-mail: php-dev-help@lists.php.net > To contact the list administrators, e-mail: php-list-admin@lists.php.net

« previous php.dev (#61440) next »