Archive - Originally posted on "The Horse's Mouth" - 2009-02-04 18:04:43 - Graham Ellis
You may have heard me talk about "injection attacks" and that having register_globals set to on in PHP makes you liable to be caught by them. Well - that's a little bit dramatic as you can write perfectly safe PHP scripts with the setting on if you're careful. Here's an example of a script which is not secured ...
<?php
$fields = array("name","town","nkids");
$connection = mysql_connect("127.0.0.1","trainee","abc123");
mysql_select_db("graham",$connection);
$rs = mysql_query("select * from people");
$table .= "<table>";
while ($row = mysql_fetch_assoc($rs)) {
$table .= "<tr>";
foreach ($fields as $column) {
$table .= "<td>".$row[$column]."</td>";
}
$table .= "</tr>";
}
$table .= "</table>";
/* ------------------------------------------- */ ?>
<html>
<head><title>Class of '08</title></head>
<body>
<h1>Here they are</h1>
<?= $table ?>
<br>
All together doing MySQL!
</body>
</html>
Now the output SHOULD look like this:
But I can make it look like this ... VERY easily!
Did you spot the extra line of text?. What has happened?
I have used the $table variable to build up my table, using the "dot equals" operator. Fine - except that I have used it the very first time that the variable is references which means that in inherits any form values that are input via a box called table on the form that calls up the script. So all I have to do is to write such a form and I can add whatever I like at that point .. which could just be text ... or it might be Javascript I want echoed out, font changes, code to call up an image ....
The solution is to change the first "dot equals" into just "equals". That's the good programming solution. But turning register_globals off also solves the problem, as the variable would not then be populated from the form. The best solution? do both!.