<?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>Devlog &#187; Security</title>
	<atom:link href="http://devlog.info/cat/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://devlog.info</link>
	<description>One developers blog.</description>
	<lastBuildDate>Tue, 31 Aug 2010 18:45:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Why PHP&#8217;s $_REQUEST is dangerous</title>
		<link>http://devlog.info/2010/02/04/why-php-request-array-is-dangerous/</link>
		<comments>http://devlog.info/2010/02/04/why-php-request-array-is-dangerous/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 07:54:37 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://devlog.info/?p=113</guid>
		<description><![CDATA[PHP offers a convenience superglobal called $_REQUEST that coalesces input from a number of sources into one easy to use array. A common thought amongst PHP developers is that you should avoid the use of $_REQUEST -- but do you actually know why?
The prevailing misconception seems to be that having GET and POST variables mixed [...]]]></description>
			<content:encoded><![CDATA[<p>PHP offers a convenience superglobal called <a href="http://php.net/manual/en/reserved.variables.request.php">$_REQUEST</a> that coalesces input from a number of sources into one easy to use array. A common thought amongst PHP developers is that you should avoid the use of $_REQUEST -- but do you actually know why?<span id="more-113"></span></p>
<p>The prevailing misconception seems to be that having GET and POST variables mixed together is insecure. While this is true under some specific circumstances (see <em><a href="http://devlog.info/2007/09/02/cross-site-request-forgeries-csrf/">Cross-Site Request Forgeries</a></em> for a weak example) -- it isn't the main reason why $_REQUEST is insecure. In fact, combining GET and POST data is often a very useful feature. In many cases you don't really care if a variable comes from GET or POST and so using $_REQUEST in those situations can help reduce the verbosity of your code while increasing flexibility.</p>
<p>The real problem is that <em>COOKIE data</em> is also mixed into $_REQUEST. The implications of this may not be readily apparent until you start thinking like a malicious user. Any cookie ever set on a users machine will always override any GET or POST data -- creating "sticky" variable data.</p>
<p>For instance, imagine if your application uses "action=" or "do=" switches to control page commands. If an attacker some how managed to set a cookie -- perhaps through some Javascript injection -- he could set a cookie named "action" and give it the value "logout." Any users that fell victim to the cookie set would never be able to use your application because "action" would be permanently set to "logout."</p>
<p>So to sum it up:</p>
<p><strong>Question:</strong> Why is $_REQUEST insecure?<br />
<strong>Answer:</strong> Because it combines COOKIE as well as GET and POST, and the COOKIE data always takes precedence -- creating the possibility for dangerous "sticky" variables.</p>
<h4>Solutions</h4>
<p>If you're already using PHP 5.3, then you can edit your php.ini and check the <a href="http://php.net/manual/en/ini.core.php#ini.request-order">request_order</a> variable -- make sure 'C' removed. <em>This 'C' is removed by default</em>, but if you use a shared host it might've been put back for backwards-compatibility. Make sure to check!</p>
<p>Otherwise, you can easily just create your own $_REQUEST array by merging $_GET and $_POST manually as part of your global initialization routines.</p>
<pre id="raw-php-2" style="display:none; width: 1px; height: 1px; overflow: hidden;">$_REQUEST = array_merge($_GET, $_POST);</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-2" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-2'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-2">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$_REQUEST</span> = <a href="http://www.php.net/array_merge"><span style="color:#000066;">array_merge</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_GET</span>, <span style="color:#0000FF;">$_POST</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>And finally, best practice is to abstract your input reading out (see <em><a href="http://devlog.info/2009/02/07/stop-using-superglobals/">Stop using superglobals!</a></em>) so you can define yourself exactly how variables are read and from where.</p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2010/02/04/why-php-request-array-is-dangerous/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Stop using superglobals!</title>
		<link>http://devlog.info/2009/02/07/stop-using-superglobals/</link>
		<comments>http://devlog.info/2009/02/07/stop-using-superglobals/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 21:47:45 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[input]]></category>

		<guid isPermaLink="false">http://devlog.info/?p=70</guid>
		<description><![CDATA[Today I want to talk about best practices in regards to reading user input. And if you haven't already, I'm going to convince you why using PHP's superglobal arrays are bad.
Best Practice: Cast to what you want
The first part of this post is all about how important casting incoming data is. As you know, security [...]]]></description>
			<content:encoded><![CDATA[<p>Today I want to talk about best practices in regards to reading user input. And if you haven't already, I'm going to convince you why using PHP's superglobal arrays are bad.<span id="more-70"></span></p>
<h2>Best Practice: Cast to what you want</h2>
<p>The first part of this post is all about how important casting incoming data is. As you know, security rule number one is <em>never trust the user</em>. So if you are expecting an Article ID which is an integer, you should make sure that you actually got an integer.</p>
<p>The most common approch is to cast user input when you get it. So if an attacker tries to supply some arbitrary string, PHP will cast it to an integer which usually results in a harmless 0. Sure, you have precautions in place against SQL injection or XSS but by casting data to a specific type, you can greatly simplify code because you can start working under assumptions ("I know for sure that $id is a harmless integer").</p>
<p>Here are a few examples:</p>
<pre id="raw-php-10" style="display:none; width: 1px; height: 1px; overflow: hidden;">// ID's (the use of max to get rid of negatives; Usually ID's are unsigned)
$article_id = max(0, (int)$_GET['id']);

// Simple strings
$username = preg_replace('#^[a-zA-Z0-9\-_\.]$#', '', $_GET['show_user']);

// Booleans
$show_drafts = (bool)$_GET['show_drafts'];
</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-10" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-10'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-10">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// ID's (the use of max to get rid of negatives; Usually ID's are unsigned)</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$article_id</span> = <a href="http://www.php.net/max"><span style="color:#000066;">max</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC66CC;color:#800000;">0</span>, <span style="color:#006600; font-weight:bold;">&#40;</span>int<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Simple strings</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$username</span> = <a href="http://www.php.net/preg_replace"><span style="color:#000066;">preg_replace</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'#^[a-zA-Z0-9<span style="color:#000099; font-weight:bold;">\-</span>_<span style="color:#000099; font-weight:bold;">\.</span>]$#'</span>, <span style="color:#FF0000;">''</span>, <span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'show_user'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Booleans</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$show_drafts</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>bool<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'show_drafts'</span><span style="color:#006600; font-weight:bold;">&#93;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Note that this isn't really about form validation. If someone is filling out a form, you still need to make sure what they input is valid. For example, the "Simple strings" snippet above is useless to users when they're registering because you're not telling them that their input is invalid.</p>
<p>These strict casts are useful only when you don't expect users to fiddle with values. So things like <code>view.php?id=34</code> where the URL is generated by your app, or &lt;select&gt; values where the user shouldn't change values etc.</p>
<h2>Getting rid of the superglobals</h2>
<p>Well, sort of. We obviously can't completely stop using $_GET/$_POST/$_COOKIE for reading incoming data because there's no replacement. What I'm talking about is ridding your code of these superglobals -- pushing them into a special input class. A code snippet is worth a thousand words; here's what I'm talking about:</p>
<pre id="raw-php-11" style="display:none; width: 1px; height: 1px; overflow: hidden;">// Bad
$article_id = $_GET['id'];

// Better
$article_id = $input-&gt;get('id');</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-11" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-11'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-11">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Bad</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$article_id</span> = <span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Better</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$article_id</span> = <span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<h2>Why</h2>
<p>The above snippet doesn't really show off anything other than the concept. So let's talk about what this mysterious input class is meant to do, and why it's better than using superglobals.</p>
<h3>Control</h3>
<p>You don't have much control over superglobals. They are simply arrays. You can't do anything special before trying to fetch values. You might be thinking about what kind of processing you would want to do. But think about this for a moment.</p>
<p>How many times have you done something like this:</p>
<pre id="raw-php-12" style="display:none; width: 1px; height: 1px; overflow: hidden;">$article_id = (int)$_GET['id'];

// Or
if (isset($_GET['id']) {
    $article_id = (int)$_GET['id'];
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-12" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-12'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-12">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$article_id</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>int<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Or</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/isset"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$article_id</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>int<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Since you control the input class, you can add a bunch of features to make gathering and casting input really easy.</p>
<pre id="raw-php-13" style="display:none; width: 1px; height: 1px; overflow: hidden;">$article_id = $input-&gt;getInt('id');
$search_user = $input-&gt;getSimpleString('search_user');
$delete_ids = $input-&gt;getArrayOfInts('delete_ids');
$article_content = $input-&gt;getString('content');
</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-13" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-13'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-13">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$article_id</span> = <span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">getInt</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$search_user</span> = <span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">getSimpleString</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'search_user'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$delete_ids</span> = <span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">getArrayOfInts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'delete_ids'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$article_content</span> = <span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">getString</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'content'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<h4>UTF-8 Handling</h4>
<p>One place where this sort of functionality is really useful is when you've switched to using UTF-8. <a href="http://devlog.info/2008/08/24/php-and-unicode-utf-8/">As you know</a>, it is possible for UTF-8 strings to be malformed -- and this is a security risk. So every time you read strings you must make sure they're valid. Without an input class, this would be a lot of work. With an input class, you can just modify your 'getString' method to add UTF-8 checking.</p>
<h4>Stripping magic quotes</h4>
<p>Another common task PHP programmers routinely need to do is handle <a href="http://php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc">magic quotes</a>. Most of us simply <a href="http://php.net/get_magic_quotes_gpc">test to see if magic quotes is enabled</a>, and run the entire superglobal array family through a function that strips the slashes -- basically undoing this devil-feature.</p>
<p>But by doing this, you're affecting the entire app (because, well, you're modifying a superglobal of course!). This might not matter to you, but it gets a bit dangerous if you use third-party libraries.</p>
<p>A friend of mine creates Facebook applications. The Facebook PHP library is clever enough to test for magic quotes and strips slashes out for values it needs. But what if you're a clever PHP programmer, and you stripped out the slashes as part of your "global.php" file? FB doesn't know that, so it just strips them again! This is an example of how modifying global data is a bad idea.</p>
<p>By moving input-reading into your own class, you can do whatever the hell you want to your data and can rest assured knowing you didn't affect anything else.</p>
<h3>Abstraction</h3>
<p>By creating this new class, you abstract the details of <em>how</em> input is gathered. You might be wondering why this is important -- isn't there just get/post/cookie? No! While the vast majority of your webpages will only use these types of input, there are certainly others. Here are two that jump to my mind.</p>
<h4>Command-Line</h4>
<p>If you make command-line scripts, getting arguments may be a perfect use for your input class.</p>
<h4>Friendly-URL's</h4>
<p>$_GET only works for values encoded in the query string. But if you are a creating an app with friendly URL's, values are sometimes embedded right into the URL. </p>
<p>For example: <code>/article/42/edit</code></p>
<p>This URL might mean to "edit" the article with ID of "42". Most frameworks, like Zend Framework's MVC components, make creating URL's like these very easy. In ZF, you define a <em>route</em> with placeholders of the values:</p>
<pre id="raw-php-14" style="display:none; width: 1px; height: 1px; overflow: hidden;">$router-&gt;addRoute('article_action', new Zend_Controller_Router_Route(
    'article/:article_id/:action',
    array('controller' =&gt; 'article', 'action' =&gt; 'view')
));</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-14" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-14'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-14">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$router</span>-&gt;<span style="color:#006600;">addRoute</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'article_action'</span>, <span style="color:#000000; font-weight:bold;">new</span> Zend_Controller_Router_Route<span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF0000;">'article/:article_id/:action'</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'controller'</span> =&gt; <span style="color:#FF0000;">'article'</span>, <span style="color:#FF0000;">'action'</span> =&gt; <span style="color:#FF0000;">'view'</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>The framework provides a way to get the value of 'article_id' and 'action' that you could plug right into your input class. It might look something like this:</p>
<pre id="raw-php-15" style="display:none; width: 1px; height: 1px; overflow: hidden;">$article_id = $input-&gt;getIntFromUrl('article_id');
$action = $input-&gt;getStringFromUrl('action');</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-15" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-15'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-15">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$article_id</span> = <span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">getIntFromUrl</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'article_id'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$action</span> = <span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">getStringFromUrl</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'action'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<h2>Building an input class</h2>
<p>Building your own input class is an excersice you can complete yourself. But I'll get you started.</p>
<p>First of all, what is our goal?</p>
<ul>
<li>Ability to clean data</li>
<li>Ability to get data from multiple sources</li>
</ul>
<p>I think a well-designed system calls for a handful of classes:</p>
<ul>
<li><code>Cleaner</code> takes values and cleans/casts them to a correct data type. We're using a separate class because it's not directly tied to input -- we might reuse this functionality elsewhere.</li>
<li><code>InputSource_*</code> are classes that read raw data from some source. We have one reader for each source. For example, <code>InputSource_Array</code> for reading information from an array (like supergloabls) or <code>InputReader_Url</code> for reading information from a friendly URL.
<li><code>InputReader</code> is the main class that ties the <code>Cleaner</code> and the <code>InputSource_*</code> classes together.
</ul>
<p>Here's how it might work:</p>
<pre id="raw-php-16" style="display:none; width: 1px; height: 1px; overflow: hidden;">$cleaner = new Cleaner();
$input = new InputReader($cleaner);
$input-&gt;addSource('req', new InputSource_Array($_REQUEST));
$input-&gt;addSource('get', new InputSource_Array($_GET));
$input-&gt;addSource('post', new InputSource_Array($_POST));
$input-&gt;addSource('cookie', new InputSource_Array($_COOKIE));
$input-&gt;setDefaultSource('req');

$input-&gt;getInt('id'); // Get from the 'req' source, a default
$input-&gt;getInt('id', 'get'); // Get from 'get' source

// $input-&gt;getInt() calls a corresponding $cleaner method to
// clean an integer.</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-16" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-16'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-16">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$cleaner</span> = <span style="color:#000000; font-weight:bold;">new</span> Cleaner<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$input</span> = <span style="color:#000000; font-weight:bold;">new</span> InputReader<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$cleaner</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">addSource</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'req'</span>, <span style="color:#000000; font-weight:bold;">new</span> InputSource_Array<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_REQUEST</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">addSource</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'get'</span>, <span style="color:#000000; font-weight:bold;">new</span> InputSource_Array<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">addSource</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'post'</span>, <span style="color:#000000; font-weight:bold;">new</span> InputSource_Array<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_POST</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">addSource</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'cookie'</span>, <span style="color:#000000; font-weight:bold;">new</span> InputSource_Array<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_COOKIE</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">setDefaultSource</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'req'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">getInt</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// Get from the 'req' source, a default</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$input</span>-&gt;<span style="color:#006600;">getInt</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'id'</span>, <span style="color:#FF0000;">'get'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// Get from 'get' source</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// $input-&gt;getInt() calls a corresponding $cleaner method to</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// clean an integer. </span></div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2009/02/07/stop-using-superglobals/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Cross-Site Request Forgeries (CSRF)</title>
		<link>http://devlog.info/2007/09/02/cross-site-request-forgeries-csrf/</link>
		<comments>http://devlog.info/2007/09/02/cross-site-request-forgeries-csrf/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 01:08:40 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[csrf]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://devlog.info/2007/09/02/cross-site-request-forgeries-csrf/</guid>
		<description><![CDATA[Today I want to cover a kind of security issue that is not addressed very often. Just about any book or article aimed at developers has some warning about XSS and SQL injection. Those two attacks are arguably two of the most harmful, but there are certainly other things to be weary of. In this [...]]]></description>
			<content:encoded><![CDATA[<p>Today I want to cover a kind of security issue that is not addressed very often. Just about any book or article aimed at developers has some warning about XSS and SQL injection. Those two attacks are arguably two of the most harmful, but there are certainly other things to be weary of. In this post I will talk about Cross-Site Request Forgeries or CSRF ("see-surf").<span id="more-22"></span></p>
<h2>CSRF Explained</h2>
<p>CSRF is a type of exploit that allows an attacker to send a request to your application with the authority of another user and without that users consent. Sometimes these requests might mean little (i.e., the user is a guest so they can't do any harm) but other times the requests can be very dangerous and destructive (i.e., the user is an administrator).</p>
<h3>How It's Done</h3>
<p>There are a number of ways that a request can be made against your server without any user interaction. The most basic and probably most often used technique is with a simple HTML image tag:</p>
<pre id="raw-html-24" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;img src=&quot;http://example.org/somescript.php&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lhtml-24" style="float:right"><a href="#" onclick="javascript:showCodeTxt('html-24'); return false;">Plain Text</a></span><span class="langName">HTML:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="html-24">
<div class="html">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/img.html"><span style="color: #000000; font-weight: bold;">&lt;img</span></a> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">"http://example.org/somescript.php"</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">"1"</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">"1"</span> /<span style="color: #000000; font-weight: bold;">&gt;</span></a></span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Even though the script handling the request ("somescript.php") might not be a valid image, it doesn't matter. The request is still being made. And by providing a width/height of 1 pixel, we can be certain the user doesn't even suspect anything is wrong.</p>
<p>Other ways might include using an iframe in the same way, or using automatic redirects.</p>
<h3>How It's Dangerous</h3>
<p>By being able to make requests so easily and without any interaction on the users part leaves services open for attack. As an example say we have an administrators control panel that lets admins delete articles on a website. An attacker might somehow get an admin to visit his website with an image tag on it:</p>
<pre id="raw-html-25" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;img src=&quot;http://example.org/admincp/delete_article.php?id=42&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lhtml-25" style="float:right"><a href="#" onclick="javascript:showCodeTxt('html-25'); return false;">Plain Text</a></span><span class="langName">HTML:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="html-25">
<div class="html">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/img.html"><span style="color: #000000; font-weight: bold;">&lt;img</span></a> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">"http://example.org/admincp/delete_article.php?id=42"</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">"1"</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">"1"</span> /<span style="color: #000000; font-weight: bold;">&gt;</span></a></span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>The danger comes when the admin happens to have an active session. If the session is controlled by cookies or IP address etc. then this request will be made with all of the authority of the admin. It would be as if the admin made the request purposefully.</p>
<p>You might be thinking that it would be a simple matter to prevent such an attack by using POST data instead of GET data. If you used POST data then the ID in the URL would not be accepted. While it does create another barrier for a potential attacker (which is always good), it doesn't solve the problem. Consider this code fragment:</p>
<pre id="raw-html-26" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;form action=&quot;http://example.org/admincp/delete_article.php&quot; method=&quot;post&quot; id=&quot;theform&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;id&quot; value=&quot;42&quot; /&gt;
&lt;/form&gt;
&lt;script type=&quot;text/javascript&quot;&gt;document.getElementById('theform').submit();&lt;/script&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lhtml-26" style="float:right"><a href="#" onclick="javascript:showCodeTxt('html-26'); return false;">Plain Text</a></span><span class="langName">HTML:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="html-26">
<div class="html">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/form.html"><span style="color: #000000; font-weight: bold;">&lt;form</span></a> <span style="color: #000066;">action</span>=<span style="color: #ff0000;">"http://example.org/admincp/delete_article.php"</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">"post"</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"theform"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"hidden"</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"id"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"42"</span> /<span style="color: #000000; font-weight: bold;">&gt;</span></a></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/form&gt;</span></span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/script.html"><span style="color: #000000; font-weight: bold;">&lt;script</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text/javascript"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>document.getElementById('theform').submit();<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Placing a 1x1 iframe with that code in it would achieve almost the same result as the 1x1 image, but this time using a POST request. Using POST over GET adds little security in this regard.</p>
<h2>Protecting Against CSRF Attacks</h2>
<p>There are a few general practices you should employ:</p>
<ul>
<li>Always use POST for important actions. This doesn't provide much protection (see above) but it does add another small barrier for an attacker to overcome. And it is generally good practice as it prevents users from performing harmful requests too easily (i.e., pasting a URL to a friend, bookmarks, etc). Using POST will also prevent any "fly-by" attacks. For example, consider a BBCode system on a message board. Using BBCode you can easily insert images into forum posts, but it is impossible to insert a hidden iframe (let alone Javascript). With such systems, to use the auto-submitting form above an attacker would have to actually trick an admin to visit a separate site.</li>
<li>In some languages like PHP, you can get all incoming data in a common way. For example, in PHP you can use the $_REQUEST superglobal to get data from cookies, GET or POST. You should avoid the use of such convenience methods and always specify a specific location for where values should be coming from.</li>
<li>Don't rely on confirmation forms or confirmation pages. The attacker will simply modify his request to indicate a "confirmed" action. For example, he might only need to add &#038;confirmed=1 to the URL or add a "confirm" hidden field to a form. Confirmation pages are only effective when preventing human error, not for preventing attacks.</li>
</ul>
<h3>Easy: Deny Off-Site Referrers</h3>
<p>One easy way to prevent CSRF attacks is to deny all POST requests from off-site domains. But this solution has a problem of its own: Not all users send the referrer header.</p>
<p>Every browser should send a referrer with each request, but there are dozens of hacks, mods or plugins that lets a user turn this feature off (some people see it as a privacy concern). So for these users you have a couple of choices: The first is to deny these users outright (probably not advisable except for special circumstances), and the second is to only enforce the referrer requirement when the referrer was in fact provided.</p>
<p>I choose to use the latter of the two choices. Since most users <em>do</em> provide a referrer, it is a great way to at least prevent the majority of people from falling victim to CSRF attacks. If the user does not provide a referrer, then we can rely on other means of protection (read more below).</p>
<p>Also a problem exists with the so-called <em>dereferer</em> services. There are some services available (and some proxy sites) that intentionally change the referrer of requests that run through them to protect the identity of the people using them (i.e., changes example.org to otherexample.net). Most internet security suites <em>blank out</em> the referrer, but that is easy to handle by just specially handling blank or missing referrers. If a user is using a dereferer service then there's no way for you to know if the request they make is real (and the referrer was modified intentionally) or fake (and the referrer is from an attacker site).</p>
<p>It's up to you to decide if these problems are worth the added security. What I do is to auto-pass all blank or invalid referrers so I can rely on other protection mechanisms (see the next section). The problem with dereferers is small, not many people use them. So I count it as an acceptable risk when important functionality is concerned.</p>
<p>Here is a function you can use in your own applications that will return false when the referrer is invalid. You can optionally supply a whitelist of domains that are allowed, other then the current working domain:</p>
<pre id="raw-php-27" style="display:none; width: 1px; height: 1px; overflow: hidden;">/**
 * Check the users referrer on POST requests to make sure
 * they come from the correct domain.
 *
 * @param array $whitelist An array of domains that should be
 *                         allowed regardless of the current domain.
 *
 * @return boolean True if the referer is allowed, false otherwise.
 */
function check_post_referrer($whitelist = array()) {

	// Only POST requests should be checked
	if (strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {
		return true;
	}

	$whitelist = (array)$whitelist;

	#------------------------------
	# Get the referrer host
	#------------------------------

	$ref_parts = @parse_url($_SERVER['HTTP_REFERER']);
	$ref_host = false;

	if ($ref_parts AND isset($ref_parts['host']) AND $ref_parts['host']) {
		$ref_host = $ref_parts['host'];
	}

	// No referrer, default to true
	if (!$ref_host) {
		return true;
	}

	#------------------------------
	# Get the current host and add
	# it to the whitelist
	#------------------------------

	$host = false;

	if ($_SERVER['HTTP_HOST']) {
		$host = $_SERVER['HTTP_HOST'];
	} else if ($_ENV['HTTP_HOST']) {
		$host = $_ENV['HTTP_HOST'];
	} else if ($_SERVER['SERVER_NAME']) {
		$host = $_SERVER['SERVER_NAME'];
	} else if ($_ENV['SERVER_NAME']) {
		$host = $_ENV['SERVER_NAME'];
	}

	if ($host) {
		array_unshift($whitelist, $host);
	}

	// If for some reason there are no allowed hosts,
	// default to true
	if (!$whitelist) {
		return true;
	}

	#------------------------------
	# Check the referrer against
	# allowed domains
	#------------------------------

	$valid = false;

	foreach ($whitelist as $check_host) {

		$check_host = trim($check_host);

		// Check with a space on each side to easily
		// anchor it without using regex

		if (stripos(&quot; $ref_host &quot;, &quot; $check_host &quot;) !== false) {
			$valid = true;
			break;
		}
	}

	return $valid;
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-27" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-27'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-27">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">/**</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * Check the users referrer on POST requests to make sure</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * they come from the correct domain.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> *</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * @param array $whitelist An array of domains that should be </span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> *&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;allowed regardless of the current domain.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> *</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * @return boolean True if the referer is allowed, false otherwise.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> */</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">function</span> check_post_referrer<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$whitelist</span> = <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// Only POST requests should be checked</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/strtoupper"><span style="color:#000066;">strtoupper</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'REQUEST_METHOD'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> != <span style="color:#FF0000;">'POST'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">true</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$whitelist</span> = <span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#0000FF;">$whitelist</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># Get the referrer host</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$ref_parts</span> = @<a href="http://www.php.net/parse_url"><span style="color:#000066;">parse_url</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'HTTP_REFERER'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$ref_host</span> = <span style="color:#000000; font-weight:bold;">false</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$ref_parts</span> AND <a href="http://www.php.net/isset"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$ref_parts</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'host'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> AND <span style="color:#0000FF;">$ref_parts</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'host'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$ref_host</span> = <span style="color:#0000FF;">$ref_parts</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'host'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// No referrer, default to true</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!<span style="color:#0000FF;">$ref_host</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">true</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># Get the current host and add</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># it to the whitelist</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$host</span> = <span style="color:#000000; font-weight:bold;">false</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'HTTP_HOST'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$host</span> = <span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'HTTP_HOST'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_ENV</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'HTTP_HOST'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$host</span> = <span style="color:#0000FF;">$_ENV</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'HTTP_HOST'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'SERVER_NAME'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$host</span> = <span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'SERVER_NAME'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_ENV</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'SERVER_NAME'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$host</span> = <span style="color:#0000FF;">$_ENV</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'SERVER_NAME'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$host</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_unshift"><span style="color:#000066;">array_unshift</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$whitelist</span>, <span style="color:#0000FF;">$host</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// If for some reason there are no allowed hosts,</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// default to true</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!<span style="color:#0000FF;">$whitelist</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">true</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># Check the referrer against</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># allowed domains</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$valid</span> = <span style="color:#000000; font-weight:bold;">false</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">foreach</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$whitelist</span> <span style="color:#616100;">as</span> <span style="color:#0000FF;">$check_host</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$check_host</span> = <a href="http://www.php.net/trim"><span style="color:#000066;">trim</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$check_host</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// Check with a space on each side to easily</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// anchor it without using regex</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>stripos<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">" $ref_host "</span>, <span style="color:#FF0000;">" $check_host "</span><span style="color:#006600; font-weight:bold;">&#41;</span> !== <span style="color:#000000; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$valid</span> = <span style="color:#000000; font-weight:bold;">true</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">break</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#0000FF;">$valid</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Example usage:</p>
<pre id="raw-php-28" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php
if (!check_post_referrer()) {
    die('Invalid referrer');
}

// Process form
// ...

?&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-28" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-28'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-28">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!check_post_referrer<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/die"><span style="color:#000066;">die</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Invalid referrer'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Process form</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// ...</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">?&gt;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>A small aside here: Note that the header for the HTTP referrer is spelled incorrectly as "referer" (hence a missing "r"). This somehow made it into the HTTP standard. If you implement your own version of this function be sure you intentionally misspell "referer".</p>
<p><strong>Note</strong> that this method is quite effective but is <em>still</em> not the holy grail. Referrer headers can be spoofed by an attacker in a couple of different ways. For example, in Flash the attacker can send a completely custom request to the server including a specially written referrer (though as I understand it, the latest version of Flash does not allow the altering of certain headers including the referrer). Other technologies may be prone to such abuse like Java applets or ActiveX controls.</p>
<h3>Effective: Unique Tokens</h3>
<p>The referrer check described above is easy to implement on a global scale, but as I explained, has some pitfalls. A more effective way to prevent CSRF is by authenticating each form with a special, unique token. This method is very effective and suffers from virtually no workarounds, but it's takes a bit more work for you as the programmer.</p>
<p>Basically you create a temporary token that is unguessable. Each time the user views a form, you generate another unguessable token. Once the user submits the form, you check the token to make sure it is valid. This makes it very difficult for an attacker to submit a form since there is no way he can get the token correct. If the token provided is incorrect, then you simply do not process the form.</p>
<p>Here's a simple implementation using sessions:</p>
<pre id="raw-php-29" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php

session_start();

$token = md5(microtime() . mt_rand(0, 1000) . mt_rand(0, 1000) . mt_rand(0, 1000));
$_SESSION['token'] = $token;

?&gt;
&lt;form action=&quot;somescript.php&quot; method=&quot;post&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;token&quot; value=&quot;&lt;?php echo $token; ?&gt;&quot; /&gt;
&lt;!-- The rest of your form --&gt;
&lt;/form&gt;
</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-29" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-29'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-29">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/session_start"><span style="color:#000066;">session_start</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$token</span> = <a href="http://www.php.net/md5"><span style="color:#000066;">md5</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/microtime"><span style="color:#000066;">microtime</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <a href="http://www.php.net/mt_rand"><span style="color:#000066;">mt_rand</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC66CC;color:#800000;">0</span>, <span style="color:#CC66CC;color:#800000;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <a href="http://www.php.net/mt_rand"><span style="color:#000066;">mt_rand</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC66CC;color:#800000;">0</span>, <span style="color:#CC66CC;color:#800000;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <a href="http://www.php.net/mt_rand"><span style="color:#000066;">mt_rand</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC66CC;color:#800000;">0</span>, <span style="color:#CC66CC;color:#800000;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$_SESSION</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'token'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF;">$token</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;form action=<span style="color:#FF0000;">"somescript.php"</span> method=<span style="color:#FF0000;">"post"</span>&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;input type=<span style="color:#FF0000;">"hidden"</span> name=<span style="color:#FF0000;">"token"</span> value=<span style="color:#FF0000;">"&lt;?php echo $token; ?&gt;"</span> /&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;!-- The rest of your form --&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;/form&gt; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>And when you process the form, you check to make sure the token in the POST data is valid:</p>
<pre id="raw-php-30" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php

if ($_POST['token'] != $_SESSION['token']) {
	die('Invalid token.');
}

// Process form</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-30" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-30'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-30">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_POST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'token'</span><span style="color:#006600; font-weight:bold;">&#93;</span> != <span style="color:#0000FF;">$_SESSION</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'token'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/die"><span style="color:#000066;">die</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Invalid token.'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Process form </span></div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>There are different ways of saving the token of course. An alternate version might be to insert tokens into a database and then delete them after use. An advantage of this method is that a user can load multiple pages at the same time, all of which can have valid tokens. Using the session script above, the token will be overwritten on each subsequent page load. In todays world of multiple windows and tabbed browsing, it might be worthwhile to allow multiple tokens to co-exist. The only important aspect is to ensure that a token expires (either it can be used only once, or it has a lifetime, or both) and that it is unguessable.</p>
<p>Using the token method of protection does mean you have to create some way of generating tokens on every form and checking the validity of the tokens whenever you process a form. This can introduce some extra work for you, but it is well worth the effort. I'm sure you can think of ways to make an efficient token system that simply plugs right into your template system and form validation scheme.</p>
<h2>Conclusion</h2>
<p>You've certainly given lots of thought to XSS and SQL injection, the two most talked about vulnerabilities in web software. Today I hope I've either introduced you to a third big security issue or at least provided you with some information you didn't think about before. </p>
<p>Check your apps for CSRF vulnerbilities, they might be a little hard to notice until you really think about them. But even the big guys make mistakes. A while back, the major social news site <a href="http://digg.com/">digg</a> suffered from this kind of attack. The site works by allowing users to "vote" on news stories to decide if the story is popular. Spammers used a CSRF attack to make any user that visited their site automatically vote for their story. Protect yourself! Use the techniques described in this post to add security to potential attack points in your applications.</p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2007/09/02/cross-site-request-forgeries-csrf/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Password Security</title>
		<link>http://devlog.info/2007/05/29/password-security/</link>
		<comments>http://devlog.info/2007/05/29/password-security/#comments</comments>
		<pubDate>Tue, 29 May 2007 22:33:09 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[md5]]></category>
		<category><![CDATA[passwords]]></category>
		<category><![CDATA[sha1]]></category>

		<guid isPermaLink="false">http://devlog.info/2007/05/29/password-security/</guid>
		<description><![CDATA[Almost every website has some sort of members-only area. Anything from a profile system to something as simple as email subscriptions for articles. What every members area has in common is some way for a user to authenticate themselves. Most likely, this is through a username and a password. What I'm going to talk about [...]]]></description>
			<content:encoded><![CDATA[<p>Almost every website has some sort of members-only area. Anything from a profile system to something as simple as email subscriptions for articles. What every members area has in common is some way for a user to authenticate themselves. Most likely, this is through a username and a password. What I'm going to talk about today is the best practices for storing and handling passwords, since they should never be stored in plain text.<span id="more-7"></span></p>
<p>The first thing you may ask is <em>why</em>? Why shouldn't passwords be stored in plaintext? The answer is pretty simple: security. You should never store anything valuable in plaintext. While your database (or wherever else you use to store this kind of information) is usually secure from prying eyes, you want to secure the information in such a way that it is virtually useless to anyone who happens to see it. This can be anyone from another admin that is snooping through the database, to a cracker that somehow got access to the data. Many people use the same password at multiple sites, so a plaintext password in the wrong hands can really lead to some serious complications.</p>
<h2>Storing Passwords</h2>
<p>The password you store should be a <em>hashed</em> version of the password. This prevents just anyone from reading the password and is the simplest way to secure your system.</p>
<p>For those of you who do not know what a hash is, I'll take the time to try and explain it simply. A hash function takes some data (for example, a password) and converts it into some fixed-length series of bits usually represented in hexadecimal characters. The result of the function is always the same for the same data. It is irreversible. Unlike a cryptographic algorithm which is designed to be reversed with the correct key, a hash function is only designed to generate this "fingerprint". A hash function is also designed so that any two different pieces of data never produce the same result (this is not entirely true, but close enough).</p>
<p>In PHP there are two popular hash algorithms for you to use: <a href="http://php.net/md5">md5()</a> and <a href="http://php.net/sha1">sha1()</a>. I would recommend the use of sha1() which is a bit more secure. Here are two examples of these functions and the result they produce:</p>
<pre id="raw-php-37" style="display:none; width: 1px; height: 1px; overflow: hidden;">echo md5('devlog'); // f4606349b811ff614a35f1406030eba9
echo sha1('devlog'); // bc4d22b5ce9923f9e52b5636b3dc2e9fd499a187</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-37" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-37'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-37">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <a href="http://www.php.net/md5"><span style="color:#000066;">md5</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'devlog'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// f4606349b811ff614a35f1406030eba9</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <a href="http://www.php.net/sha1"><span style="color:#000066;">sha1</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'devlog'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// bc4d22b5ce9923f9e52b5636b3dc2e9fd499a187 </span></div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Combine the attributes of a hash function (unique, irreversible, and nonsensical) and you get the perfect solution to secure passwords. Applying this concept to your applications is dreadfully simple. Where you would normally store a plaintext password, you now store the hashed password:</p>
<pre id="raw-php-38" style="display:none; width: 1px; height: 1px; overflow: hidden;">mysql_query(&quot;
	INSERT INTO users SET
		user = '&quot; . mysql_real_escape_string($username) . &quot;',
		password = '&quot;. sha1($input_password) .&quot;'
&quot;);</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-38" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-38'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-38">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; INSERT INTO users SET</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; &nbsp; &nbsp; user = '"</span> . <a href="http://www.php.net/mysql_real_escape_string"><span style="color:#000066;">mysql_real_escape_string</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$username</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <span style="color:#FF0000;">"',</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; &nbsp; &nbsp; password = '"</span>. <a href="http://www.php.net/sha1"><span style="color:#000066;">sha1</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$input_password</span><span style="color:#006600; font-weight:bold;">&#41;</span> .<span style="color:#FF0000;">"'</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">"</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Once you do this, there is one other aspect you need to take care of: logging in. Since the user would supply their password in plaintext, you need to hash their password before testing it against the one you have stored. There are usually two different methods programmers use to authenticate a user. The first is to use an SQL query with a WHERE clause so the passwords must match to return any row, the second is to just grab the user row and then compare the passwords in PHP. I will be using the second method.</p>
<p>Here's how your login code might look. Of course, $username and $input_password would filled with form values:</p>
<pre id="raw-php-39" style="display:none; width: 1px; height: 1px; overflow: hidden;">$res = mysql_query(&quot;
	SELECT * FROM users
	WHERE username = '&quot; . mysql_real_escape_string($username) . &quot;'
&quot;);

if (!mysql_num_rows($res)) {
	die('Invalid username.');
}

$user = mysql_fetch_assoc($res);

if ($user['password'] != sha1($input_password)) {
	die('Invalid password.');
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-39" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-39'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-39">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$res</span> = <a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; SELECT * FROM users</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; WHERE username = '"</span> . <a href="http://www.php.net/mysql_real_escape_string"><span style="color:#000066;">mysql_real_escape_string</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$username</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <span style="color:#FF0000;">"'</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!<a href="http://www.php.net/mysql_num_rows"><span style="color:#000066;">mysql_num_rows</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$res</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/die"><span style="color:#000066;">die</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Invalid username.'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$user</span> = <a href="http://www.php.net/mysql_fetch_assoc"><span style="color:#000066;">mysql_fetch_assoc</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$res</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$user</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'password'</span><span style="color:#006600; font-weight:bold;">&#93;</span> != <a href="http://www.php.net/sha1"><span style="color:#000066;">sha1</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$input_password</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/die"><span style="color:#000066;">die</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Invalid password.'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>As you can see, it's just a matter of comparing the already hashed password from the database with the hashed version of the inputted password. If they don't match, then the user inputted the incorrect password.</p>
<p>Just this small alteration to your save and login code has increased your security substantially, it's is worth the ten minutes of work.</p>
<h2>Other Concerns</h2>
<p>We already know that a hash function cannot be reversed, but there are still ways to get the original string.</p>
<h3>Brute Forcing</h3>
<p><img src='http://devlog.info/wp-content/uploads/2007/05/password-brute-force-demo.gif' alt='Brute Force Demonstration' align="right" style="border:1px solid #888;" /> A brute for attack is where the attacker has the hash for a password and continually tries one string after the other until he finds one that matches. For example, he might try 'a', then 'b' ... 'ab', 'ac' etcetera for all permutations of the alphabet. This takes a <em>long</em> time for long strings, but a relatively short amount of time for shorter ones. The amount of time is also increased when you introduce more characters (for example if you let users input punctuation characters).</p>
<h3>Dictionary Attacks</h3>
<p><img src='http://devlog.info/wp-content/uploads/2007/05/password-dictionary-attack-demo.gif' alt='Dictionary Attack Demonstration' align="right" style="border:1px solid #888;" /> A dictionary attack is similar to the a brute force attack but instead of trying every single possible combination of characters, the attacker uses a dictionary and only tries the words in the dictionary. This attack can be very useful since the majority of non-tech savvy people will use passwords like 'pussycat99' and these are the kinds of strings good dictionaries will contain. Since the number of strings to test will be dramatically lower then the number a brute force will have to try, this can crack a password extremely quickly if it is not a secure password. Since most web applications are designed to be as user friendly as possible, it is not often that developers enforce good password policies on users so this problem is still something to worry about.</p>
<h3>Rainbow Table Lookups</h3>
<p><img src='http://devlog.info/wp-content/uploads/2007/05/password-rainbow-table-demo.gif' alt='Rainbow Table Lookup Demonstration' align="right" style="border:1px solid #888;" /> A rainbow table is a huge database of pre-computed hashes. This is where someone hashes every possible string (usually up to a certain length) and saves the hash. When an attacker wants a password, he just checks this massive database for the hash. If the hash is found, he can easily see the corresponding string that made it. These databases are usually really big, but it is not common for a rainbow table to contain records past 8 characters.</p>
<h2>The Solution: Use A Salt</h2>
<p>The most common solution to all of these problems is to use a <em>salt</em>. Note that a salt only adds security when talking about trying to reverse a hash back into the original string. It is not meant to protect against multiple login attempts from an attacker trying to gain access to a user account (though if the attacker already has the hash then it may be the ultimate goal). For those kinds of attacks, you should enforce an account lock-out feature. For example, only allow 3 consecutive incorrect login attempts before locking the account for an hour or emailing the administrator with details.</p>
<p>A salt is basically a random string that you append to the users password. The salt is stored separately and is used purely to prevent the aforementioned attacks. The salt itself doesn't need to be secret, just the fact that it is appended to the password thwarts most password attacks. To generate a salt, you simply get random characters. For example, here's an example generate_salt() function:</p>
<pre id="raw-php-40" style="display:none; width: 1px; height: 1px; overflow: hidden;">/**
 * Generates a random salt from ASCII characters 33-126. These
 * characters include all letters, numbers and punctuation.
 *
 * @param integer $len How long you want the salt to be
 * @return string The generated salt
 */
function generate_salt($len = 8) {

	$min = 33;
	$max = 126;

	$salt = '';

	for($i = 0; $i &lt;$len; $i++) {
		$salt .= chr(mt_rand($min, $max));
	}

	return $salt;
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-40" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-40'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-40">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">/**</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * Generates a random salt from ASCII characters 33-126. These</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * characters include all letters, numbers and punctuation.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> *</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * @param integer $len How long you want the salt to be</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * @return string The generated salt</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> */</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">function</span> generate_salt<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$len</span> = <span style="color:#CC66CC;color:#800000;">8</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$min</span> = <span style="color:#CC66CC;color:#800000;">33</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$max</span> = <span style="color:#CC66CC;color:#800000;">126</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$salt</span> = <span style="color:#FF0000;">''</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">for</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$i</span> = <span style="color:#CC66CC;color:#800000;">0</span>; <span style="color:#0000FF;">$i</span> &lt;<span style="color:#0000FF;">$len</span>; <span style="color:#0000FF;">$i</span>++<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$salt</span> .= <a href="http://www.php.net/chr"><span style="color:#000066;">chr</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/mt_rand"><span style="color:#000066;">mt_rand</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$min</span>, <span style="color:#0000FF;">$max</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#0000FF;">$salt</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Now when you save a password you append the salt and save both the salt and the salted password. Our save code above might be altered like this:</p>
<pre id="raw-php-41" style="display:none; width: 1px; height: 1px; overflow: hidden;">$salt = generate_salt();

mysql_query(&quot;
	INSERT INTO users SET
		user = '&quot; . mysql_real_escape_string($username) . &quot;',
		password = '&quot;. sha1($input_password . $salt) .&quot;',
		salt = '&quot; . mysql_real_escape_string($salt) . &quot;'
&quot;);</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-41" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-41'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-41">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$salt</span> = generate_salt<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; INSERT INTO users SET</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; &nbsp; &nbsp; user = '"</span> . <a href="http://www.php.net/mysql_real_escape_string"><span style="color:#000066;">mysql_real_escape_string</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$username</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <span style="color:#FF0000;">"',</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; &nbsp; &nbsp; password = '"</span>. <a href="http://www.php.net/sha1"><span style="color:#000066;">sha1</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$input_password</span> . <span style="color:#0000FF;">$salt</span><span style="color:#006600; font-weight:bold;">&#41;</span> .<span style="color:#FF0000;">"',</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; &nbsp; &nbsp; salt = '"</span> . <a href="http://www.php.net/mysql_real_escape_string"><span style="color:#000066;">mysql_real_escape_string</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$salt</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <span style="color:#FF0000;">"'</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">"</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>In doing so, a password <em>mypass</em> effectively becomes <em>mypasscGdZPSEj</em>. The random bit at the end means any attack is much much slower if not impossible. A brute force attack will become almost impossible with a long salt. A rainbow table lookup will most likely fail since there are certainly no databases that contain more then 10 character strings (most only go up to 8). A dictionary attack will be slowed down substantially when an attacker is trying to crack multiple passwords since each password will have a different salt and thus will need to be hashed separately.</p>
<h3>Authentication With A Salt</h3>
<p>If you are storing salted passwords, you once again have to change the way you authenticate. Just like how a plaintext password had to be hashed to be compared with the stored password, you need to hash and salt the inputted password before comparing. The above authentication code could be written like this:</p>
<pre id="raw-php-42" style="display:none; width: 1px; height: 1px; overflow: hidden;">$res = mysql_query(&quot;
	SELECT * FROM users
	WHERE username = '&quot; . mysql_real_escape_string($username) . &quot;'
&quot;);

if (!mysql_num_rows($res)) {
	die('Invalid username.');
}

$user = mysql_fetch_assoc($res);

if ($user['password'] != sha1($input_password . $user['salt'])) {
	die('Invalid password.');
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-42" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-42'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-42">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$res</span> = <a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; SELECT * FROM users</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; WHERE username = '"</span> . <a href="http://www.php.net/mysql_real_escape_string"><span style="color:#000066;">mysql_real_escape_string</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$username</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <span style="color:#FF0000;">"'</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!<a href="http://www.php.net/mysql_num_rows"><span style="color:#000066;">mysql_num_rows</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$res</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/die"><span style="color:#000066;">die</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Invalid username.'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$user</span> = <a href="http://www.php.net/mysql_fetch_assoc"><span style="color:#000066;">mysql_fetch_assoc</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$res</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$user</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'password'</span><span style="color:#006600; font-weight:bold;">&#93;</span> != <a href="http://www.php.net/sha1"><span style="color:#000066;">sha1</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$input_password</span> . <span style="color:#0000FF;">$user</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'salt'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/die"><span style="color:#000066;">die</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Invalid password.'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Notice how on line 12 the salt is appended to $input_password.</p>
<h2>What About 'Lost Password' Forms?</h2>
<p>When you don't store the plaintext version of a password, it becomes impossible to send a user their password if they ever loose it. That's just the way things are. But that doesn't mean the user has no hope, you just have to take another approach. Instead of <em>Lost</em> Password forms, create <em>Reset</em> Password forms. Instead of sending the user an email with their password, send them a link with a special code that will reset the password and then send them the newly generated one. After they have logged in again with the new password they are free to go and change it to whatever they want.</p>
<h2>Conclusion</h2>
<p>I hope you've learned something today. I have seen many applications that still store passwords in plaintext, and it scares me a bit. I myself use a program on my Macintosh called <a href="http://www.xheadsoftware.com/info_xhead.asp">info.xhead</a> that stores all of my passwords for important things. Most of my passwords are 18 random characters, even I don't know what they are. But there are some common websites that I still use one password for (shame on me, I just can't be bothered to log into all of those old sites). It scares me because if an attacker gets hold of my one password, I sometimes wonder what other websites he will be able to gain access to. The Priate Bay, a torrent website, was recently hacked and the attacker gained all of the user information. Fortunately all of the passwords were hashed, but what if they weren't? I wonder how many users signed up with the same password as the password they used for their email account. Imagine how many compromised email accounts the attacker could have had access to. So do the world a favor: hash your passwords, and add in a dash of salt to make everything that much better.</p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2007/05/29/password-security/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
