Jump to content

SOLVED: variable variables


skaterdav85

Recommended Posts

I am trying to dynamically create variables from the GET array using the array index as the variable name. I figured variable variables would be the way to do this, but I'm not quite sure how to implement it. Here is what I have so far:Here is my URL w/ the query string:http://localhost/phppractice/results.php?f...p;submit=Submit

foreach($_GET as $key => $value){	$$each = $key;	}echo $lastname;

SOLVED:if anyone is curious, this is the solution:

foreach($_GET as $key => $value){	$a = $key;	$$key = $value;}

Link to comment
Share on other sites

See the manual page for a detailed example... basically, the values of variables that you may think of your own could instead be influeced by the $_GET variables, and there's no way to check up if it's not, short of using the $_GET variable itself, which sort of defeats the point.

Link to comment
Share on other sites

ohh i kind of see what you mean. That link you posted above says "register_globals will inject your scripts with all sorts of variables, like request variables from HTML forms". What do these injected variables look like? Even with it on, don't you have to access post/get data through the post/get superglobals?So when you have a lot of form fields, is it still better to use POST/GET data by assigning them to variables first (even though this can be tedious), and then using those variables, so that you know what variables you have created?

Link to comment
Share on other sites

Consider something like this:

<?phpif (!empty($_SESSION['userid'])){  $result = mysql_query('SELECT admin FROM users WHERE id=' . $_SESSION['userid']);  if ($row = mysql_fetch_assoc($result) && $row['admin'] == '1')  {	$is_admin = true;    }}...if (isset($is_admin)){  // do some admin stuff}?>

What happens if you go to that page with register_globals on (or your method) and you add is_admin=1 to the URL?

Link to comment
Share on other sites

The injected variables look just like normal variables... that's the problem. Their name corresponds to the key in either of GET, POST, COOKIE, SERVER, SESSION, perhaps even ENV arrays, and the value is whatever value is there, perhaps each next array overriding the next or whatever.With register_globals on, you don't have to access the superglobals. You can instead access the injected variable itself. You can always access $lastname, if it's defined anywhere, and if it's not created, it will be created at the first value change (if any).With register_globals off, it's safe to initialize the variable manually, as long as you're aware where the variable is coming from, and know each variable. Performing overgeneralizations like yours is only good if you don't have any other variables in your main scope, which is basically true for register_globals also.If all variables from one source have a certain common purpose, it's best to perform the purpose upon the actual traversing of the $_GET array... like, if you're supposed to insert them into a DB, perform mysqli_real_escape_string() there, and join them to the query... right there.If there are multiple purposes, consider making the different portions as arrays (you know, where you give the name attribute a name like "purpose[item1]"), and then switch the processing based on the $_GET subarray.

Link to comment
Share on other sites

Oh ok, I didn't know register_globals did that. That must have been a nightmare if you had both POST and GET data with the same index.The reason I asked this was because i had to take a PHP test for a job interview, and one of the questions it asked was that above, except for POST data instead of the GET array. I never actually thought of doing this, but now I see how it might make it harder to debug your script and it presents a whole lot of security issues especially if register_globals is on. Do you have any insight as to why this was asked if it is considered bad practice?

Link to comment
Share on other sites

Consider something like this:
<?phpif (!empty($_SESSION['userid'])){  $result = mysql_query('SELECT admin FROM users WHERE id=' . $_SESSION['userid']);  if ($row = mysql_fetch_assoc($result) && $row['admin'] == '1')  {	$is_admin = true;    }}...if (isset($is_admin)){  // do some admin stuff}?>

What happens if you go to that page with register_globals on (or your method) and you add is_admin=1 to the URL?

So something like this could be done with any variable name in any script? So if register_globals is on and you have a variable in your script that variable could be manipulated just by adding "&varName=value" to the URL? How do you stop this and why does register_globals even exist?! Or am I completely misunderstanding?
Link to comment
Share on other sites

CODEforeach($_GET as $key => $value){ $$each = $key; }echo $lastname;
$$each = $key; what does this double dollar means?
Link to comment
Share on other sites

The reason I asked this was because i had to take a PHP test for a job interview, and one of the questions it asked was that above, except for POST data instead of the GET array. I never actually thought of doing this, but now I see how it might make it harder to debug your script and it presents a whole lot of security issues especially if register_globals is on. Do you have any insight as to why this was asked if it is considered bad practice?
It depends how the question was phrased, they might have asked it to see if you know about the security implications.
So something like this could be done with any variable name in any script? So if register_globals is on and you have a variable in your script that variable could be manipulated just by adding "&varName=value" to the URL? How do you stop this and why does register_globals even exist?! Or am I completely misunderstanding?
The only reason that exploit works in that script is because $is_admin does not get initialized. If $is_admin=false; was at the top the exploit wouldn't work. So one way to avoid attacks like that is to make sure that you initialize any variables you're going to be checking like that. Everything should have a default value. The variables in your script don't get overwritten, they are just pre-defined when the script starts. If you have some section of code that uses a variable like that without explicitly defining it first, then it's open to an exploit like that.
Link to comment
Share on other sites

It depends how the question was phrased, they might have asked it to see if you know about the security implications.
The question asked me to write a function that loops over the POST array and dynamically creates variables using the array key as the variable name.
Link to comment
Share on other sites

its called a variable variable. Wierd name haha, but read http://php.net/manual/en/language.variables.variable.php for more on it,
i think it is asigninga variable name by another variable's value. did not know about that.another new thing. :) have to read that. thanks
Link to comment
Share on other sites

Interesting that they specified the POST array. It sounds like they really did bait you. I mean, they gave you a chance to say, "Why the FFF would I want to do a dumb thing like that?" Executed at the wrong part of your script, a thing like that actually could overwrite data in your script.Basically, they asked you to reconstruct the functionality of register_globals, which has shipped OFF for a while, and is now deprecated. They asked you to create a thing that PHP itself has deprecated. If that's not an intentional bait, these guys must be radically stupid.How many programmers habitually use variables with names like $password or $logged_in ? So imagine you set $logged_in to false based on a DB query, and then run this crazy routine they asked you to write. Suddenly, $logged_in is true, and your script might dish out someone's account info. Ouch! No hacker expects tricks like this to work all the time. That's why they stay up all night trying every server they can hit.The interviewers probably made it POST instead of GET to see if you knew that POST data can be manipulated almost as easily as GET data.

Link to comment
Share on other sites

Shadow, I'm sure that like a lot of stuff, register_globals was originally a developer convenience, and it took a while before someone noticed how it could be exploited, so now, finally, it's gone.

Link to comment
Share on other sites

The only reason that exploit works in that script is because $is_admin does not get initialized. If $is_admin=false; was at the top the exploit wouldn't work. So one way to avoid attacks like that is to make sure that you initialize any variables you're going to be checking like that. Everything should have a default value. The variables in your script don't get overwritten, they are just pre-defined when the script starts. If you have some section of code that uses a variable like that without explicitly defining it first, then it's open to an exploit like that.
Ah, I see. Good thing I'm in the habit of initializing my variables...:)
Shadow, I'm sure that like a lot of stuff, register_globals was originally a developer convenience, and it took a while before someone noticed how it could be exploited, so now, finally, it's gone.
Things like that seem to happen quite often...:) Hindsight is 20/20 as they say. :)
Link to comment
Share on other sites

so i tried retrieving the value of the register_globals directive, and it doesn't echo out 'Off', which is what i see when i run phpinfo(). in my conditional block, it does echo out 'blank string', but the function returns a blank string only on failure. why would there be a failure?

echo 'register_globals '.ini_get('register_globals');echo '<br/>';echo 'allow_url_fopen: '.ini_get('allow_url_fopen');echo '<br/>';if(ini_get('register_globals') === NULL){	echo 'null';	}if(ini_get('register_globals') === ''){	echo 'blank string';	}

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...