Security in PHP. Part I
The simplest way to exclude the opportunity of compromising your code is to think about such opportunities at the stage of writing that code. You have to understand that your code is the part of the protection system.
Let’s show one example that can lighten developer’s work.
<?php
function write_text($filename, $text="") {
static $open_files = array();
// if filename equals null, close all opened files
if ($filename == NULL) {
foreach($open_files as $fr) {
fclose($fr);
}
return true;
}
$index = md5($filename);
if(!isset($open_files[$index])) {
$open_files[$index] = fopen($filename, "a+");
if(!$open_files[$index]) return false;
}
fputs($open_files[$index], $text);
return true;
}
?>
By default that function has two parameters: filename and text that should be written in the indicated file. At first, function checks whether file has been opened earlier or not. If it has been opened function uses old indicator. If transferred to the function file name equals NULL all files will be closed.
If developer uses that function his code will be clearer. Let’s suppose that our function is situated in the file included to the scripts. Here we have one of such scripts, called quotes.php:
<form action="<?=$_SERVER["PHP_SELF"]?>" method="get">
Choose the theme of expression:
<select name="quote" size="3">
<option value="funny">Humor</option>
<option value="political">Politics</option>
<option value="love">About love</option>
</select><br />
The quote: <input type="text" name="quote_text" size="30" />
<input type="submit" value="Save Quote" />
</form>
</body></html>
<?php
include_once("write_text.php");
$filename = "/home/web/quotes/{$_GET["quote"]}";
$quote_msg = $_GET["quote_text"];
if (write_text($filename, $quote_msg)) {
echo "<center><hr><h2>Expression saved!</h2></center>";
} else {
echo "<center><hr><h2>Erorr</h2></center>";
}
write_text(NULL);
?>
So, as you can see on creating the system developer used write_text() function. Unfortunately, that script can be used by malefactor for evading the protection system on the web-server.
Let’s view the following URL:
http://www.somewhere.com/fun/quotes.php?quote=different_file.dat"e_text=garbage+data
What can happen if server gets the query with such URL? quotes.php will be executed of course, but in spite of recording the expressions to the specified files there will be created new file different_file.dat. And garbage data line will be recorded to it. In fact, malefactor can create new account if he gets the access to the file with passwords having pointed in the parameter ../../../etc/passwd. Probably, the most serious consequence by means of that script is recording and executing of different PHP script.
There are several ways out. If you don’t have a lot of files you can use the associative array for storing file names. Or you can check files’ extensions for making sure that server won’t run them.
You have to think what can happen if form sends false data; does the malefactor have any opportunities for changing the behavior of the script? You have to find all possible breaches system, otherwise malefactors can do it.
Typical mistakes concerned with security
Mistake 1. When we trust the input data.
Never trust the input data received from the external sources. It is the main idea of my reasoning about the security of the PHP script. All data received from the form, locally situated files or the environment variables should be checked and formatted.
Mistake 2. When we store the vulnerable data in the web-server tree.
All vulnerable data should be stored in the separate file and directory. When they are required they can be connected to the script by means of require() or include().
Mistake 3. When we ignore the security recommendations.
It is very important to think about server protection! Everything depends on experience; soon you will be able to find all potential gaps in your code.



