I previously ran across some code that used import_request_variables to set all post, get and cookie parameters to global variable. This saved time since you would not need to explicitly call:
123
if(isset($_GET['some_param']) and $_GET['some_param']){ $some_var = $_GET['some_param'];}
It was called using:
1
import_request_variables('GPC','_') ;
This code was called on every page of the site. The first parameter ‘GPC’ tells import_request_variables to import get, post and cookie parameters. The second parameter ‘_’ tells import_request_variables to add a underscore to the variable name. For example, passing $_GET[‘foo’] will create a variable called $_foo. If the second parameter is passed, there will be a E_NOTICE warning since this would allow any user to create or modify any variable. In this code, the underscore was provided as a prefix but this does not mean we are in the clear security wise. Before I show the example, lets draw up some example code for index.php.
<?#the following code is example code #and should not be used as an example#of the "right" way of doing things. #There may even be syntax errors.#starts the session, connects to db, #and calls import_request_variablesfunctionbegin(){session_start();mysql_connect('localhost','mysql_user','mysql_password');import_request_variables('GPC','_');}#checks username and password with db#and sets $_SESSION['user_id'] if they authenticate successfully. functionlogin($username,$password){$username=mysql_real_escape_string($username);$password=mysql_real_escape_string($password);#as stated above, this code is only an example,#for a real site you would want a hash/salt, not plaintext#password.$query="SELECT * FROM users WHERE username = '$username' and password = '$password' LIMIT 1";$result=mysql_query($query);$user=mysql_fetch_assoc($result);if($user){$_SESSION['user_id']=$user['user_id'];}}#destroys sessionfunctionlogout(){session_destroy();}#will return true if $_SESSION['user_id'] is set and belongs to a userfunctionisLoggedIn(){if(isset($_SESSION['user_id'])){$user_id=$_SESSION['user_id'];$query="SELECT * FROM users WHERE user_id = '$user_id' LIMIT 1";$result=mysql_query($query);$user=mysql_fetch_assoc($query);if($user){returntrue;}else{returnfalse;}}else{returnfalse;}}begin();#note that variables starting with #$_ where set above with import_request_variablesif(isset($_logout)){logout();}if(isset($_username)&&isset($_password)){login($_username,$_password);}if(isLoggedIn()){?> You are an authorized user! <a href='index.php?logout=true'>Logout</a>.<?}else{?> You are not authorized, use the form below to log in. <form action='index.php'> Username: <input type='text' name='username' /><br /> Password: <input type='password' name='password' /> </form><?}?>
This is a simple page which will tell you if you are authorized, or give the login form if not. If the user successfully logs in, the $_SESSION[‘user_id’] is set. $_username and $_password are set by import_request_variables if the username and password get, post or cookie variables are set. Now on to the attack. Any variable starting with $_ can be set by passing a get, post or cookie with the appropriate parameters. If a user sent the request http://www.example.com/?SESSION[user_id]=1 would overwrite the $_SESSION[‘user_id’] variable to 1. Since database ids are often sequential, it would not be that hard to use a script to run through each number and find ids that belong to users. It would essentially allow a hacker to log in as any user. Make sure if using the import_request_variables function, make sure to choose a prefix that will not be used by any other variables.