Page 2 of 4

Posted: Mon Jul 25, 2005 5:38 pm
by Roja
infolock wrote:Again, one will not know if the variable is undefined if the error reporting is off. if it's turned on (which php.net strongly suggests that you do NOT do), then yeah, you are right. again, if, however, you keep error reporting turned off for this instance, you have no worries.
YES YOU DO. The reporting being off just HIDES it. If the attacker sets that variable, it's going to be a problem.

Just because the safe is hidden, doesn't change the fact that its insecure because the door is hanging open!

You *DO* have worries.
infolock wrote:Because so long as you have the error reporting turned off, the end user is NOT going to see any of these warnings, and thus will not know of any variables that are left undefined.
Not true.

They could know because you reuse a common library. They could know because its an obvious/common/guessable variable name. They could know because they get shared hosting and find a way to view your code. They could know because they compromise the ftp stream, and see it in transit.

They could know because they run one of five common automated vulnerability testers against it, which don't have to know variable names at all - they simply try a wide range of common variables and values that often result in insecurity.

The point is - you are arguing that HIDING an open safe full of money is SECURE. Its not. Its inscure. You can secure the safe properly, and then you can tell the world it is there and it won't matter.

Obscurity is NOT security.

Posted: Mon Jul 25, 2005 5:50 pm
by Chris Corbyn

Code: Select all

exec($_GETї'cmd']);
That's to clear and everyone is probably thinking "nobody would issue exec from GET"...

Now take the scenario that register globals are turned on!

Code: Select all

$cmd = 'rm -rvf '. $some_info_from_a_database_maybe;
//Yadda yadda

exec($cmd);
Now it's not clear that there's a way to input that from the URL but if your script is poorly written (i.e. $cmd is sometimes undefined *cough* ) AND register globals is on (omg we could have a disaster now)...

You get the picture. I'm not disagreeing about turning off error roprting in production but YES do ALL of your development with E_ALL.... keep the code clean.

Posted: Tue Jul 26, 2005 4:18 am
by Skittlewidth
timvw wrote: PHP $line .= "message"
VB line = line & "message"
That was my point, in php you don't have to explicitly specify the variable the second time. Just a minor annoyance thats all. Will read that article you recommended now. Thanks

Posted: Tue Jul 26, 2005 6:51 am
by timvw
Well, you could write your own pre-compiler in PHP :p

Code: Select all

$vbcode = file_get_contents('test.vbs');
$vbcode = preg_replace('#(\w+)\s*\.=\s*(\"\w+\")#', '$1 = $1 & $2', $vbcode);
echo nl2br($vbcode);

Posted: Sun Jul 31, 2005 2:53 pm
by infolock
Roja : the point you make is fine IF someone uses a common library of variables.. that's IF someone uses that common variable names. In the end though, if they actually DO something like that, wouldn't you say that they are gonna be screwed no matter HOW they code? Because if they are using that kinda variable scheme, then they are going to be wide open in general.

But what you just showed was a pre-defined variable (NOT an undefined variable) that is executed. And you are also assuming that this variable is going to be used for system control usage.

In the long run, so long as someone checks to validate any information they are going to be exceuting (which is strongly recommended by the entire php community for security purposes), they will be fine.

As for it hiding the varible, that is EXACTLY my point! If the variable names and meaning are hidden, then yes the person is secure SO LONG as they practice safe variable naming. But this is my last point on this. Even if you use a nother variable writing scheme, and even if you make your script as secure as possible, there will be hackers out there who will want to exploit any type of security holes you have in general.

That's why you would configure apache to validate any script coming in, apply correct security measurements to your network infrastructure, and validate any/all code you are wanting to process.

IF you follow those rules, and have E_ALL turned off, you have no worries. Production sites should NOT have E_ALL turned on due to security issues in general. Testing sites that are located locally on the programmers' pc and does not effect the production websites can have E_ALL reporting turned on to test any/all code they possess.

But you need to understand, your theory of someone being hacked has a flaw due to your assumption they are using common variable naming schemes. Again, if they are doing this, they are already screwed as they have a really good chance of having a lot more worries and security vulnerablities aside from a variable name and it's purpose.

But the whole point of this conversation isn't URL passing. $_GET is used when globals are turned off. Therefore, the variable YOU are trying to argue on is a variable related to globals being turned ON! Not off! I"m talking about a variable that consists of a result. IE : a result from a table query, or a result from a file read. Or any number of other variables. If that variable (say it's $bob) is defined, we want to perform another action. If it's not assigned, we want to exit :

Code: Select all

if($bob) {
 //do something
} else {
  exit;
}
this is a very valid statement even if it DOES give errors when you ahve E_ALL on. But the whole point of this conversation is the fact that you should have E_ALL OFF, not ON on production sites. If you are testing, again, it's no big deal. If you are live, then it's a very big deal. I agree with you there. But you have to agree that if I name a variable $_MySQL_Result, or $_Jon_Result_to_EXPORT_HOME, what harm is there in this? I use naming schemes that are common, but common ONLY for me, not the rest of the world. But so long as we validate that variable, check it and strip it to ensure we are recieving what we want, we have no real security threat that hasn't already existed from the beginning of time.

ONLY AN IDIOT would name a variable $cmd = my_shell_command_here. And if that person uses that naming scheme, I say let him/her be hacked due to the ignorance they are performing to their coding practices.

Posted: Sun Jul 31, 2005 3:18 pm
by Roja
infolock wrote:Roja : the point you make is fine IF someone uses a common library of variables.. that's IF someone uses that common variable names.
No. Now your counter argument is "Its hidden well enough, as long as you choose obscure variable names".

Yet again - your argument does not convert obscurity into security.
infolock wrote: As for it hiding the varible, that is EXACTLY my point! If the variable names and meaning are hidden, then yes the person is secure SO LONG as they practice safe variable naming.
No. Obscurity does not equal security. Once more, if I know the variable name, I can attack. Thats not secure.

If you leave my site and go to yours, the referrer will show your ultra-hard-to-guess variable in the url! http://www.example.com/index.php?variab ... _guess=555 will show up in my referrer log, and then I can exploit at will. The same is true for sniffing, for shared hosting, for a dozen other scenarios.

Obscurity is NOT security.
infolock wrote: But you need to understand, your theory of someone being hacked has a flaw due to your assumption they are using common variable naming schemes.
No, based on experience, I know for a fact that it happens - even without common variable naming schemes. I gave a simple example to highlight the reasons for that.

You continue to misunderstand the difference between security and obscurity.
infolock wrote: But you have to agree that if I name a variable $_MySQL_Result, or $_Jon_Result_to_EXPORT_HOME, what harm is there in this? I use naming schemes that are common, but common ONLY for me, not the rest of the world
The naming scheme *doesnt* matter. You have totally missed the point. As I said, I used a simple example to highlight how dangerous undefined variables are. You are choosing to attack the example, instead of listening to the core argument.

You continue to argue that obscurity = security, and it doesnt. Having a unique naming scheme does *nothing* to improve the security. It only forces the attacker to find the variable names. There are dozens of ways for him to do so, and many are trivial and passive.

In the alternative, by simply adding *ONE* line of code, complying with coding standards, and best practices, the variable naming doesn't matter AT ALL! You *CAN* name it $cmd, and the attacker can know, and it will still be secure - BECAUSE YOU DEFINE IT, overriding the attacker's attempts.

Posted: Sun Jul 31, 2005 4:00 pm
by Roja
Its time to let others do the arguing on why its important to initialize variables:
PHP Security Consortium wrote: A best practice is to initialize all variables and to develop with error_reporting set to E_ALL, so that the use of an uninitialized variable won't be overlooked during development.
http://phpsec.org/projects/guide/1.html
IBM's guide to auditing PHP wrote: The first step is to turn PHP's error_reporting setting up to E_ALL. This will result in PHP reporting a warning every time an uninitialized variable is used, each bad file access, and other (mostly) harmless errors, but might also represent a potential attack vector. These errors nearly always indicate sloppy programming, so if it's your code, you should clean them up anyway.
http://www-128.ibm.com/developerworks/o ... y/os-php1/
The fine manual wrote: ...it really is generally a good programming practice to initialize variables first...
Always validate your user data and initialize your variables!
http://us3.php.net/register_globals
O'reillys top ten security checks for PHP wrote:Write code to initialize all global variables
http://www.onlamp.com/pub/a/php/2003/03 ... urity.html
Devnet site PHPAdvisory wrote: Because of this danger... ANY of your variables has the potential to have a user injected initial value. You can protect against this kind of attack by configuring PHP not to make external variables globally available. Or you can make sure that you ALWAYS initialize your variables before using them.
http://www.phpadvisory.com/articles/view.phtml?ID=5

If those aren't good enough for you, I don't know how to explain it better. Its a best practice, its the right way to do it, and its a risk not to, no matter what your naming convention is.

Posted: Sun Jul 31, 2005 4:20 pm
by nielsene
I agree with Roja. I've almost thrown away otherwise good PHP books when they say its "good security practice" to name you directory containing admin scripts something crazy like "adgae7risfdh" instead of "admin".

Makes me realize the author knows nothing about real security issues.

Posted: Mon Aug 01, 2005 1:45 pm
by infolock
Roja : if you feel that you are right on this, let's have a look see if you can break it ? Cuz i'm telling you man, you are wrong here.

I can setup a page in a matter of minutes that will contain 30 variables that are undefined. If you show me you can break it using your methods verses mine, I'll bow down to you.


Shall__We__Play__A..__GAME__? :D

Posted: Mon Aug 01, 2005 2:10 pm
by Roja
infolock wrote:Roja : if you feel that you are right on this, let's have a look see if you can break it ? Cuz i'm telling you man, you are wrong here.
You are asking me to continue to validate an industry best practice. Its documented everywhere from secure programming books, to the php manual, from the php security consortium, to virtually every tutorial on the net.

You are also breaking the cardinal rule of secure programming - you are assuming it IS secure, and asking for one person to prove it is NOT. Secure programming starts at the opposite end. Everything is insecure, prove it is not.

To that point, I've cited example after example of people saying word-for-word that you should not leave variables undefined. Its documented, its best practice, I've given examples, I've explained, and you still ask for further proof.

You either understand that obscurity isnt security, or you don't. Feel free to take it up with the PHP mailing list, the PHP security consortium, the Secure Programming (PHP) book authors, and so forth.

For me, any further discussion on it will just turn childish and non-helpful. If you have any further questions about it, ask any of the authors I cited.

Posted: Mon Aug 01, 2005 2:39 pm
by nielsene
On top of everything Roja has already said...

If you're using "non-predictable" variables names as an attempt at security through obscurity, those names are probably slightly longer and/or more "jumbled" than they should be. Readability goes down, mis-typeability goes up, and if you have errors off you won't know that you mis-typed it leading to some annoying bug-hunts.

Posted: Mon Aug 01, 2005 4:43 pm
by Ambush Commander
Personally, I think you two are talking past each other. Infolock purports that a page with undefined variables can be secure. Roja is sure that obscurity is not security and that the industry's best practice is to initialize all variables.

Don't you see? You're both right!

I can make a page with thirty uninitialized variables and I can make it completely secure (disregarding PHP and Apache security). I can also make that same page and initialize all the variables and claim it is safer. There is nothing inherently insecure about uninitialized variables, and if we were perfect beings, we could program our programs perfect enough that uninitialized variables didn't have an effect.

The problem is that we're not perfect. We tend to lose track of the variables we toss around and we tend to add functionality that can introduce security errors. This, methinks, is Roja's point: it's not a good idea to have uninitialized variables. Infolock's point is that uninitialized variables are not inherently insecure. There's a difference.

Of course, I could have misinterpreted. :oops:

Posted: Mon Aug 01, 2005 5:09 pm
by Roja
Ambush Commander wrote:Of course, I could have misinterpreted.
You did.
Ambush Commander wrote:I can make a page with thirty uninitialized variables and I can make it completely secure (disregarding PHP and Apache security).
No. Uninitialized variables are not secure. They can be defined by the user.

Do we trust user-defined variables? Ever? No. They are unsafe, and not secure.
Ambush Commander wrote:There is nothing inherently insecure about uninitialized variables, and if we were perfect beings, we could program our programs perfect enough that uninitialized variables didn't have an effect.
Yes, there is something inherently insecure about them. You cannot make a loop that uses an upper bound set by a variable which is uninitalized and have it be secure:

for ($i=0; $i<$evil; $i++)
{
dostuff();
}

If evil is NOT initialized, then if evil is set to a high enough value, my script will not complete. Period. Thats not secure.

On the other hand, if I *do* initialize the variable to say, 5, then the user can do whatever they want to $evil, and it wont matter - because its set at 5.

Thats secure.

Infolock is arguing that because the user doesn't know the variable name is $evil, he can't override it. That much is somewhat true.

There are dozens of ways to find the variable name. Infolock hasn't argued that point.

There are dozens of ways to cause problems once you know the variable name. Infolock hasn't argued that point.

So you have two choices. Infolock suggests hiding the variable name which, if exposed can be exploited.

I, along with most of the Information Security industry, suggest that you instead define the variable, so even if you know the variable name, it is secure.

Which is better?

Obscurity or security?

Its a binary question, and its an easy choice.

Posted: Mon Aug 01, 2005 6:19 pm
by McGruff
Uninitialised variables are categorically, unquestionably insecure. There really is no argument and I can't let that statement pass on a forum where many people are learning to code.

As has been mentioned, the variable can be set to any value by a hacker under certain conditions.

(1) Undefined vars in the global scope when register globals is on. $_GET['foo'] is automatically declared as a global variable $foo. Hackers can set any values for GET vars with a bit of query string tampering. Similarly with $_POST and $_COOKIE.

(2) Undefined vars in any scope where the programmer does something like: extract($_POST). Fns like foreach & etc can be used to do the same thing. Undefined vars in the same scope could be set by the hacker but also vars are being declared without first validating the user-supplied values. Note that extracting is a problem regardless of whether register globals is off or on.

Claiming that you're safe just because you're using obscure variable names which a hacker cannot guess is not an acceptable security policy.

My recommendations would be:

(1) always develop with E_ALL to catch undefined vars and fix them immediately
(2) stay out of the global scope
(3) never access GPC vars directly anywhere in the code (it will lead to bad layering apart from amything else); instead use a Request object which validates values (and keys) and which doesn't let anything bad pass through - a $request->getFoo() call should return null if a foo key failed a validation test
(4) a validation system is only as good as its validation rules: make sure you understand what you need to block and test your code rigorously to make sure it behaves as expected

Posted: Tue Aug 02, 2005 10:03 am
by infolock
Ambush Commander hit the head on the nail with what I am trying to explain. McGruff, I have not said that if someone goes to extremes of hacking that a site could not be hacked. NOTHING is 100% secure. No matter WHAT you do, nothing is 100% secure. I agree, you should not leave unsecure code available, and you should use best practice coding, but all i'm saying is, i can always valididate my variables, undefined or not. I can always filter all variables (undefined or not) and make sure they are what they are. I can always do every security check in the world to an undefined variable. And you know what? IF I use my security filter checks, then I'm not gonna be abused or exploited for having an undefined variable. So long as I validate any data that may reside within that variable, that's all I need to do.

I understand it's not the best coding practice. Hell, I've only said that 15 times throughout this entire discussion. But I've said, and will continue to say, that if you check your variables, you validate your variables, and you ensure that the data you are recieving is what you had inteneded, you can most definately use undefined variables without worrying. Because so long as you take the necessary steps of preventing any type of malicious code being impliemented into your script, you are going to be ok so far as the scope of php security and network security will permit you to be.

I am by no means saying that php is 100% secure. NOTHING is 100% secure. But I NEVER said to use global variables. I said that was the worst thing. And you should NEVER EVER use E_ALL in a LIVE site. It should only be used in development sites ONLY.

With that said, ambush is more correct on this. I feel that both sides are right, but both sides are also wrong. You say tomoto, i say hamburger.

EDIT : Btw, like I said Roja, any time you want to try this out, we can man. I'm not trying to be a punk, I'm just merely wanting to show you that what I'm trying to say is valid, secure, and easy to use so long as you follow secure coding practices like validating ....