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;">&lt;?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;">?&gt;</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">&#39;aidan&#39;</span> AND <span class="nv">password</span><span class="o">=</span><span class="s1">&#39;&#39;</span> OR <span class="s1">&#39;&#39;</span><span class="o">=</span><span class="s1">&#39;&#39;</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!

Comments