<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ElbertF &#187; security</title>
	<atom:link href="http://elbertf.com/tag/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://elbertf.com</link>
	<description>Insights and Updates from a Tech Geek</description>
	<lastBuildDate>Fri, 23 Jul 2010 09:12:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Escaping and sanitizing user input in PHP</title>
		<link>http://elbertf.com/2010/07/escaping-and-sanitizing-user-input-in-php/</link>
		<comments>http://elbertf.com/2010/07/escaping-and-sanitizing-user-input-in-php/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 09:12:09 +0000</pubDate>
		<dc:creator>ElbertF</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[escaping]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sanitizing]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://elbertf.com/?p=606</guid>
		<description><![CDATA[I recently answered a question on Quora, a questions and answers website that I frequent. The poster asked &#8220;what are best practices for escaping or sanitizing user input in PHP?&#8221; People seemed to appreciate the answer I wrote so I&#8217;ll post it here and elaborate on it a bit&#160;more. Why is it important to sanitize [...]]]></description>
			<content:encoded><![CDATA[<p>I recently answered a question on <a href="http://quora.com">Quora</a>, a questions and answers website that I frequent. The poster asked &#8220;<a href="http://www.quora.com/what-are-best-practices-for-escaping-or-sanitizing-user-input-in-PHP">what are best practices for escaping or sanitizing user input in PHP?</a>&#8221; People seemed to appreciate the answer I wrote so I&#8217;ll post it here and elaborate on it a bit&nbsp;more.</p>
<h4>Why is it important to sanitize user&nbsp;input?</h4>
<p>If you&#8217;re not careful with user input your website might be open to <a href="http://en.wikipedia.org/wiki/Code_injection">code injection</a>, <a href="http://en.wikipedia.org/wiki/Directory_traversal">directory traversal</a> or similar attacks. Information supplied by users can never be assumed&nbsp;safe.</p>
<p>Examples of user input are submitted forms (e.g. comments), URL parameters (?q=example) and server-side scripts pulling in third-party data, such as an RSS feed&nbsp;importer.</p>
<p><span id="more-606"></span></p>
<h4>HTML and&nbsp;JavaScript</h4>
<p>To make strings safe for HTML (without breaking <a href="http://www.unicode.org/standard/WhatIsUnicode.html">Unicode text</a>) use&nbsp;<a href="http://php.net/manual/en/function.htmlentities.php"><code>htmlentities()</code></a>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$safe</span> <span style="color: #339933;">=</span> <span style="color: #990000;">htmlentities</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$unsafe</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>This will encode all special HTML characters. This method is better than black-listing specific elements such as &lt;script&gt; or just opening tags (&lt;). Do not use <a href="http://php.net/manual/en/function.strip-tags.php"><code>strip_tags()</code></a>, <a href="http://php.net/manual/en/function.str-replace.php"><code>str_replace()</code></a> or <a href="http://www.php.net/manual/en/book.pcre.php">regular expressions</a> to filter HTML and JavaScript, it is easy to miss obscure vulnerabilities and leave them&nbsp;exploitable.</p>
<p>When automatically parsing a URL to display a clickable link, check if URL starts with a protocol like &#8220;http://&#8221; (regex: <code>/[a-z]:\/\//i</code>) and make sure <code>javascript:</code> links never work. Also be careful with quotes and closing angle brackets as they can break&nbsp;HTML.</p>
<p>These examples demonstrate how unfiltered links can be&nbsp;dangerous:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'javascript:alert(\'XSS\');'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://example.com&quot; onclick=&quot;alert(\'XSS\');'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'example.com&quot;&gt;&lt;script&gt;alert(\'XSS\');&lt;/script&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$url</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;Click here&lt;/a&gt;</pre></td></tr></table></div>

<h4>URLs</h4>
<p>To pass values as a parameter to a URL, use&nbsp;<a href="http://php.net/manual/en/function.rawurlencode.php"><code>rawurlencode()</code></a>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://example.com/?k='</span> <span style="color: #339933;">.</span> <span style="color: #990000;">rawurlencode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>This function is nearly identical to <a href="http://php.net/manual/en/function.urlencode.php"><code>urlencode()</code></a> but follows the <a href="http://www.faqs.org/rfcs/rfc1738.html">RFC 1738</a>&nbsp;specification.</p>
<h4>MySQL database&nbsp;queries</h4>
<p>When storing strings in a MySQL database, use&nbsp;<a href="http://php.net/manual/en/function.mysql-real-escape-string.php"><code>mysql_real_escape_string()</code></a>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$safe</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$unsafe</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Often <a href="http://php.net/manual/en/function.addslashes.php"><code>addslashes()</code></a> is used instead but this is not enough to prevent <a href="http://www.owasp.org/index.php/SQL_Injection">SQL injection attacks</a>. If you want to learn why I recommend reading <a href="http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string">this blog post</a> by Chris Shiflett and the third chapter of the <a href="http://dev.mysql.com/tech-resources/articles/guide-to-php-security-ch3.pdf">guide to PHP security</a> by Ilia Alshanetsky (PDF,&nbsp;130KB).</p>
<p>This function requires a MySQL&nbsp;connection.</p>
<h4>Magic&nbsp;Quotes</h4>
<p>If your web app suffers from unwanted backslashes appearing in content this is probably due to double escaping (e.g. &#8220;today&#92;&#8217;s weather&#8221;). This is likely caused by PHP&#8217;s now deprecated <a href="http://php.net/manual/en/security.magicquotes.php">Magic&nbsp;Quotes</a>.</p>
<p>Magic Quotes is a feature automatically escapes user input, intended to help beginners write more secure code. Because it&#8217;s not always on or needed this affects portability and requires excessive use of <a href="http://www.php.net/manual/en/function.stripslashes.php">stripslashes()</a> to&nbsp;undo.</p>
<p>To recursively undo the affects of Magic Quotes use this function at the beginning of your&nbsp;scripts:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">function</span> undo_magic_quotes<span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">array_map</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'undo_magic_quotes'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'get_magic_quotes_gpc'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">get_magic_quotes_gpc</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$_GET</span>    <span style="color: #339933;">=</span> <span style="color: #990000;">array_map</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'undo_magic_quotes'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$_POST</span>   <span style="color: #339933;">=</span> <span style="color: #990000;">array_map</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'undo_magic_quotes'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$_COOKIE</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_map</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'undo_magic_quotes'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<h4>Directories</h4>
<p>And finally, be careful with including files using user&nbsp;input.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">// Don't do this</span>
<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'file'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// And especially not this</span>
<span style="color: #b1b100;">echo</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'file'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>This is dangerous because a user can request any file from the server and execute or view the code (e.g. &#8220;?file=../../config.php&#8221;, this is called a <a href="http://www.owasp.org/index.php/Category:Path_Traversal_Attack">path traversal attack</a>). One solution is to use <a href="http://php.net/manual/en/function.basename.php"><code>basename()</code></a> which strips off the path of a file&nbsp;name.</p>
<p>These were just a few basics, there is a lot more to web application security. <a href="http://www.owasp.org">OWASP</a> is a great resource if you want to learn&nbsp;more.</p>
]]></content:encoded>
			<wfw:commentRss>http://elbertf.com/2010/07/escaping-and-sanitizing-user-input-in-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to store passwords safely with PHP and MySQL</title>
		<link>http://elbertf.com/2010/01/store-passwords-safely-with-php-and-mysql/</link>
		<comments>http://elbertf.com/2010/01/store-passwords-safely-with-php-and-mysql/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 08:43:27 +0000</pubDate>
		<dc:creator>ElbertF</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[passwords]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://ElbertF.com/?p=447</guid>
		<description><![CDATA[First, let me tell you how not to store passwords and&#160;why. Do not store password as plain&#160;text This should be obvious. If someone gains access to your database then all user accounts are compromised. And not only that, people tend to use the same password on different sites so those accounts will be compromised as [...]]]></description>
			<content:encoded><![CDATA[<p>First, let me tell you how <strong>not</strong> to store passwords and&nbsp;why.</p>
<h4>Do not store password as plain&nbsp;text</h4>
<p>This should be obvious. If someone gains access to your database then all user accounts are compromised. And not only that, people tend to use the same password on different sites so those accounts will be compromised as well. Your site doesn&#8217;t even need to be hacked; a system administrator could easily browse your&nbsp;database.</p>
<h4>Do not try to invent your own password&nbsp;security</h4>
<p>Chances are that you&#8217;re no security expert. You&#8217;re better off using a solution that has been proven to work instead of coming up with something&nbsp;yourself.</p>
<h4>Do not encrypt&nbsp;passwords</h4>
<p><a href="http://en.wikipedia.org/wiki/Encryption">Encryption</a> may seem like a good idea but the process is reversible. Anyone with access to your code would have no trouble transforming the passwords back to their originals. <a href="http://en.wikipedia.org/wiki/Security_through_obscurity">Security through obscurity</a> is not&nbsp;sufficient!</p>
<p><span id="more-447"></span></p>
<h4>Do not use&nbsp;MD5</h4>
<p>Storing password <a href="http://en.wikipedia.org/wiki/Hash_function">hashes</a> is a step in the right direction. Cryptographic hashing functions like <a href="http://en.wikipedia.org/wiki/MD5">MD5</a> are irreversible which makes it difficult to figure out the original password. To validate a hashed password, simply hash the password again when a user logs in and compare the&nbsp;hashes.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$password</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'swordfish'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Value: 15b29ffdce66e10527a65bc6d71ad94d</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Note that this makes it impossible to retrieve a password from the database. If a user forgets his password, simply generate a new&nbsp;one.</p>
<p>So why not MD5? It is quite easy to make a list of millions of hashed passwords (a <a href="http://en.wikipedia.org/wiki/Rainbow_table">rainbow table</a>) and compare the hashes to find the original passwords (the same goes for other hashing functions like&nbsp;<a href="http://en.wikipedia.org/wiki/SHA_hash_functions">SHA-1</a>).</p>
<p>MD5 is also prone to <a href="http://en.wikipedia.org/wiki/Brute_force_attack">brute forcing</a> (trying out all combinations with an automated script) because of <a href="http://en.wikipedia.org/wiki/Collision_resistance">collisions</a>. This means that different passwords can have the same hash, making it even easier to find one that&nbsp;works.</p>
<p>MD5 collision demo:&nbsp;<a href="http://www.mscs.dal.ca/~selinger/md5collision/">mscs.dal.ca/~selinger/md5collision</a></p>
<h4>Do not use a single site-wide&nbsp;salt</h4>
<p>A <a href="http://en.wikipedia.org/wiki/Salt_%28cryptography%29">salt</a> is a string that is hashed together with a password so that most rainbow tables (or <a href="http://en.wikipedia.org/wiki/Dictionary_attack">dictionary attacks</a>) won&#8217;t&nbsp;work.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$password</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'swordfish'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$salt</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'something random'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$salt</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Value: db4968a3db5f6ed2f60073c747bb4fb5</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>This is better then using just MD5 but someone with access to your code can find the salt a generate a new rainbow&nbsp;table.</p>
<h4>What you should&nbsp;do</h4>
<ul>
<li>Use a cryptographically strong hashing function like SHA-1 or even SHA-256 (see PHP&#8217;s <a href="http://www.php.net/manual/en/function.hash.php">hash()</a>&nbsp;function).</li>
<li>Use a long and random salt for each&nbsp;password.</li>
<li>Use a slow hashing algorithm to make brute force attacks near&nbsp;impossible.</li>
<li>Regenerate the hash every time a users logs&nbsp;in.</li>
</ul>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$username</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Admin'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$password</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'gf45_gdf#4hg'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create a 256 bit (64 characters) long random salt</span>
<span style="color: #666666; font-style: italic;">// Let's add 'something random' and the username</span>
<span style="color: #666666; font-style: italic;">// to the salt as well for added security</span>
<span style="color: #000088;">$salt</span> <span style="color: #339933;">=</span> <span style="color: #990000;">hash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sha256'</span><span style="color: #339933;">,</span> <span style="color: #990000;">uniqid</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'something random'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Prefix the password with the salt</span>
<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$salt</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$password</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Hash the salted password a bunch of times</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">100000</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #990000;">hash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sha256'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$hash</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Prefix the hash with the salt so we can find it back later</span>
<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$salt</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$hash</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Value:
 * e31f453ab964ec17e1e68faacbb64f05bccceb179858b4c482c1b182ff1e440e
 * f1e10feb5b86c6d367e4eb8f90f2cde5648a7db3df8526878f20a77eed00c703
 */</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>In the above example we turned a reasonably strong password into a 128 characters long hash that we can store in a database. The next time the user logs in we can validate the password as&nbsp;follows:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$username</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Admin'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$password</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'gf45_gdf#4hg'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'
    SELECT
        `hash`
    FROM `users`
        WHERE `username` = &quot;'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&quot;
    LIMIT 1
    ;'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$r</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// The first 64 characters of the hash is the salt</span>
<span style="color: #000088;">$salt</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$r</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'hash'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">64</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$salt</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$password</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Hash the password as we did before</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">100000</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #990000;">hash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sha256'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$hash</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$salt</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$hash</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$hash</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$r</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'hash'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Ok!</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>A few additional tips to prevent user accounts from being&nbsp;hacked:</p>
<ul>
<li>Limit the number of failed login&nbsp;attempts.</li>
<li>Require strong&nbsp;passwords.</li>
<li>Do not limit passwords to a certain length (remember, you&#8217;re only storing a hash so length doesn&#8217;t&nbsp;matter).</li>
<li>Allow special characters in passwords, there is no reason not&nbsp;to.</li>
</ul>
<p>That&#8217;s it, happy&nbsp;coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://elbertf.com/2010/01/store-passwords-safely-with-php-and-mysql/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Safer web forms with security tokens</title>
		<link>http://elbertf.com/2009/11/safer-web-forms-with-security-tokens/</link>
		<comments>http://elbertf.com/2009/11/safer-web-forms-with-security-tokens/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 08:24:31 +0000</pubDate>
		<dc:creator>ElbertF</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://ElbertF.com/?p=367</guid>
		<description><![CDATA[A common issue with many web applications is their vulnerability for Cross-Site Request Forgery, or XSRF. It allows a hacker to send a malicious request to a website with an other user&#8217;s privileges. Here&#8217;s how it&#160;works: A hacker creates a page with a form that submits data to&#160;example.com. An administrator from example.com is tricked into [...]]]></description>
			<content:encoded><![CDATA[<p>
A common issue with many web applications is their vulnerability for <a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery">Cross-Site Request Forgery</a>, or XSRF. It allows a hacker to send a malicious request to a website with an other user&#8217;s privileges. Here&#8217;s how it&nbsp;works:
</p>
<ul>
<li>
A hacker creates a page with a form that submits data to&nbsp;<em>example.com</em>.
</li>
<li>
An administrator from <em>example.com</em> is tricked into visiting the page, the form is submitted using&nbsp;JavaScript.
</li>
<li>
The data is handled by <em>example.com</em> as if it came from the administrator (because it&nbsp;did).
</li>
</ul>
<p>
This allows a hacker to perform administrative tasks on <em>example.com</em> like editing pages or deleting&nbsp;users.
</p>
<p><span id="more-367"></span></p>
<h4>Solution</h4>
<p>
Probably the best solution to this problem is using a <a href="http://en.wikipedia.org/wiki/Security_token">security token</a>. This is a code (usually a <a href="http://en.wikipedia.org/wiki/Hash_function">hash</a>) that is send with the form in a hidden field and is only valid for a specific user and a certain period of&nbsp;time.
</p>
<p>
I recommend using a <a href="http://en.wikipedia.org/wiki/SHA_hash_functions">SHA1</a> hash created from these&nbsp;components:
</p>
<ul>
<li>
Information about the user (IP address, user agent,&nbsp;username).
</li>
<li>
Information about the server (hostname, software&nbsp;version).
</li>
<li>
Information about the website (database name, table&nbsp;prefix).
</li>
<li>
Information that expires (user&#8217;s session&nbsp;id).
</li>
</ul>
<p>
This will result in an unpredictable and seemingly random hash that is still verifiable by the server and difficult to&nbsp;fake.
</p>
<p>
After the form is submitted the hash is re-created and compared to the token that was send with the form. Only if the hashes match the form is processed, otherwise an error message is displayed. This way even if a hacker manages to find the user&#8217;s token the request will&nbsp;fail.
</p>
<p><strong>Example&nbsp;(PHP/HTML):</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$authToken</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sha1</span><span style="color: #009900;">&#40;</span>
  <span style="color: #990000;">session_id</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span>
  <span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span>
  <span style="color: #000088;">$dbName</span> <span style="color: #339933;">.</span>
  <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REMOTE_ADDR'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span>
  <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_USER_AGENT'</span><span style="color: #009900;">&#93;</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'submit'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'auth_token'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'auth_token'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$authToken</span> <span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Process form</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">else</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Display error message</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;form id=&quot;form&quot; method=&quot;post&quot; action=&quot;./&quot;&gt;
  &lt;fieldset&gt;
    &lt;label for=&quot;name&quot;&gt;Name:&lt;/label&gt;
    &lt;input type=&quot;text&quot; name=&quot;name&quot; id=&quot;name&quot; value=&quot;&quot;/&gt;
  &lt;/fieldset&gt;
  &lt;fieldset&gt;
    &lt;input type=&quot;hidden&quot; name=&quot;auth_token&quot; value=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$authToken</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;/&gt;
&nbsp;
    &lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Submit&quot;/&gt;
  &lt;/fieldset&gt;
&lt;/form&gt;</pre></td></tr></table></div>

<p>Note that this only really works for POST requests. For this reason GET (regular links) should never be used to pass information that is used for administrative tasks. AJAX requests should also <em>always</em> use&nbsp;POST.</p>
]]></content:encoded>
			<wfw:commentRss>http://elbertf.com/2009/11/safer-web-forms-with-security-tokens/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
