PHP Security Considerations, a Quick Reference for the Newbies.
To often I get passed code to review that quite frankly is so full of holes it wouldn’t make an adequate sieve…
So in this quick blog I outline a few simple and easily implemented steps to ensure as you start out in the world of PHP, your first site isn’t hacked within 5 minutes, leaving you a whimpering wrek …
PHP DON’T EXAMPLE 1:
Passing RAW globals to mysql!
i.e.
$sql = "SELECT * FROM users WHERE email='.$_GET['email']."' and password='".$_GET['password']"';";
$result = mysql_query($sql);
So what is wrong with the above? SQL INJECTION welcome to a world where people want to break your website, simply because they can …
I am not going to add more description, just click through to the wiki pedia entry linked above …
To avoid this PHP comes with two functions mysql_escape_string() and mysql_real_escape_string()
An example taken from the mysql_real_escape_string() page:
Example#2 An example SQL Injection Attack
<span style="color: #000000;"><span style="color: #0000bb;"><?php
</span><span style="color: #ff8000;">// Query database to check if there are any matching users
</span><span style="color: #0000bb;">$query </span><span style="color: #007700;">= </span><span style="color: #dd0000;">"SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'"</span><span style="color: #007700;">;
</span><span style="color: #0000bb;">mysql_query</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$query</span><span style="color: #007700;">);</span></span>
<span style="color: #000000;"><span style="color: #007700;"> </span><span style="color: #ff8000;">// We didn't check $_POST['password'], it could be anything the user wanted! For example:
</span><span style="color: #0000bb;">$_POST</span><span style="color: #007700;">[</span><span style="color: #dd0000;">'username'</span><span style="color: #007700;">] = </span><span style="color: #dd0000;">'aidan'</span><span style="color: #007700;">;
</span><span style="color: #0000bb;">$_POST</span><span style="color: #007700;">[</span><span style="color: #dd0000;">'password'</span><span style="color: #007700;">] = </span><span style="color: #dd0000;">"' OR ''='"</span><span style="color: #007700;">;</span></span><span style="color: #007700;"><span style="color: #ff8000;">// This means the query sent to MySQL would be:
</span><span style="color: #007700;">echo </span><span style="color: #0000bb;">$query</span><span style="color: #007700;">;
</span><span style="color: #0000bb;">?></span></span>
The query sent to MySQL:
<div class="highlight"><pre><code class="bash"><span></span>SELECT * FROM users WHERE <span class="nv">user</span><span class="o">=</span><span class="s1">'aidan'</span> AND <span class="nv">password</span><span class="o">=</span><span class="s1">''</span> OR <span class="s1">''</span><span class="o">=</span><span class="s1">''</span>
</code></pre>
</div>
This would allow anyone to log in without a valid password.
So in summary READ the mysql_real_escape_string() page, and even if you don’t implement the “best practice” example on that page PLEASE make sure you at least escape $_SESSION $_GET $_POST inputs with a mysql escape function!