Table of Content
Introduction
When on, register_globals will inject your scripts with all sorts of variables, like variables coming from GET or POST methods, from sessions and cookies. This setting can make scripts insecure, using the fact that php doesn't require initialization of variables. There is an example here http://www.php.net/register_globals of that kind of leak. This tiny text will explain another way to get rid of a login security using leaks created by register_global = ON too, but from another point of view.
Theorical considerations
There are many arrays that are initialized in a bad way, without "array();" and just by assigning an index like this :
<?php
$sample['key1'] = 'value1';
$sample['key2'] = 'value2';
?>
You probably already know that you can access to one char of a string using { } or [ ]
For more informations: PHP manual page about strings
Since php4, using [ ] instead of { } to access any char is deprecated, but still available for compatibility reasons.
So:
<?php
$string = "abcdefgh";
echo $string{2}; // 'c'
echo $string{4}; // 'e'
echo $string{0};
?>
Behaves the same as :
<?php
$string = "abcdefgh";
echo $string[2]; // 'c'
echo $string[4]; // 'e'
echo $string[0];
?>
Now what happens if you use non-numerical index?
PHP evaluate the index as 0:
<?php
$string = "abcdefgh";
echo $string['foo']; // 'a'
echo $string[0]; // 'a'
?>
You must also notice that if you modify a char with more than one char: only the first char will be used.
<?php
$string = 'abcdefgh';
$string[0] = 'yzzzzz'; // 'ybcdefgh'
$string[0] = 'y'; // 'ybcdefgh'
?>
The leak
Imagine that there is a script that use :
<?php
$admin['user'] = 'foo';
$admin['pass'] = 'bar';
if($admin['user'] == $_GET['username'] AND $admin['pass'] == $_GET['password']){
/* Give r00t */
}
?>
It could seem quite secure, but in fact, it isn't. The security leak is caused by the bad array initialization mixed with register_gobals.
Here is an example
What happens if you try to request the page with : page.php?admin=asdf
- $admin is set to 'asdf'
- $admin['user'] = 'foo'; sets the first char of 'asdf' to 'f'
- $admin['pass'] = 'bar'; sets the first char of 'fsdf' to 'b'
- $admin['user'] == $_GET['username'] tests if 'b' == $_GET['username']
- $admin['pass'] == $_GET['password'] tests if 'b' == $_GET['password']
So, to have access : simply use : page.php?admin=asdf&username=b&password=b
It means you only have to know the first character of the pass, and if you don't : try, there are not many possibilities.
Conclusion
As you can see, the security leaks caused by register_globals are not always obvious.
A good habbit to take is to disable the register_globals feature, especially if you don't use it.
Its also important to be sure the variables you're working with are defined the proper way.
RSS (general)
What is the proper way?