<?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>Coffee on the Keyboard &#187; security</title>
	<atom:link href="http://coffeeonthekeyboard.com/tag/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://coffeeonthekeyboard.com</link>
	<description>by James Socol</description>
	<lastBuildDate>Fri, 20 Apr 2012 22:17:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/>		<item>
		<title>Bleach, HTML sanitizer and auto-linker</title>
		<link>http://coffeeonthekeyboard.com/bleach-html-sanitizer-and-auto-linker-for-django-344/</link>
		<comments>http://coffeeonthekeyboard.com/bleach-html-sanitizer-and-auto-linker-for-django-344/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 19:22:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sanitize]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[user]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=344</guid>
		<description><![CDATA[Bleach is a whitelist-based HTML sanitizer and auto-linker in Python, built on html5lib, for AMO and SUMO and released under the BSD license. Bleach has two main functions: sanitizing HTML based on a whitelist of tags and attributes, and turning URLs into links. It uses html5lib for both. For more information on using Bleach, see [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/jsocol/bleach">Bleach</a> is a whitelist-based HTML sanitizer and auto-linker in Python, built on <a href="http://code.google.com/p/html5lib/">html5lib</a>, for <a href="https://addons.mozilla.org/">AMO</a> and <a href="http://support.mozilla.com/">SUMO</a> and released under the BSD license.</p>
<p>Bleach has two main functions: sanitizing HTML based on a whitelist of tags and attributes, and turning URLs into links. It uses html5lib for both.</p>
<p>For more information on using Bleach, see the <a href="http://github.com/jsocol/bleach/blob/master/README.rst">README</a> included in the source. For more info on how Bleach works, follow below the jump.<span id="more-344"></span></p>
<h3>Sanitizing HTML</h3>
<p>Bleach&#8217;s <code>clean()</code> function uses a slightly custom version of html5lib&#8217;s <code>HTMLSanitizer</code> tokenizer that adds support for per-tag attribute whitelists. Any entity that is not part of a whitelisted tag or valid entity will be encoded. Legitimate entities and tags are allowed. The default whitelist is set up for AMO.</p>
<h3>Linkifying Text</h3>
<p>The <code>linkify()</code> function is a little more complicated. Naïve implementations usually rely on a simple regular expression to find URL-like strings, but this quickly becomes insufficient when you need to handle situations like these:</p>
<ul>
<li><code>&lt;em&gt;http://example.com&lt;/em&gt;</code> (should be linkified)</li>
<li><code>&lt;a href="http://example.com"&gt;test&lt;/a&gt;</code> (already linked, no need to linkify)</li>
<li><code>&lt;a href="http://example.com"&gt;http://example.com&lt;/a&gt;</code> (really don&#8217;t need to linkify)</li>
<li><code>&lt;em&gt;http://xx.com &lt;a href="http://example.com"&gt;http://example.com&lt;/a&gt;&lt;/em&gt;</code> (regular expression freak-out)</li>
</ul>
<p>So <code>linkify()</code> actually uses html5lib to build a document fragment and walks it, only applying the naïve regular expression in safe locations. In pseudocode:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">tree = parseFragment<span class="br0">&#40;</span><span class="kw2">input</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">linkify_nodes <span class="br0">&#40;</span>tree<span class="br0">&#41;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">for</span> node <span class="kw1">in</span> tree:</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> node <span class="kw1">is</span> a text node:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; replace node with text nodes <span class="kw1">and</span> links</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="kw1">if</span> node <span class="kw1">is</span> a link:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> nofollow:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">set</span> rel=<span class="st0">&quot;nofollow&quot;</span> on node</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; linkify_nodes<span class="br0">&#40;</span>node.<span class="me1">childNodes</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">return</span> <span class="kw3">string</span><span class="br0">&#40;</span>linkify_nodes<span class="br0">&#40;</span>tree<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>This avoids attempting to apply the regular expression to things like tag attributes, the inside of <code>&lt;a&gt;</code> tags, and other places it should generally be avoided. It also lets us do things like set the <code>rel</code> attribute on links already in the text and pass the <code>href</code> attribute through the same filter it would go through if we created the link. This filter lets us redirect links through an outbound redirect, so people know they&#8217;re leaving a Mozilla site. You could do other things with it, like rickroll your visitors. That&#8217;s up to you.</p>
<h3>Bad HTML</h3>
<p>Because both <code>clean()</code> and <code>linkify()</code> use <code>html5lib</code> and construct document trees, using either will fix up code mistakes, like unclosed takes, and escape bare entities. <code>linkify()</code> allows basically every tag and attribute, so if you need to limit the legal HTML to a subset, use <code>clean()</code> (or the shortcut <code>bleach()</code> to clean then linkify).</p>
<h3>Getting Bleach</h3>
<p>Bleach is <a href="http://github.com/jsocol/bleach">available on Github</a>, or can be installed via <code>pip</code> or <code>easy_install</code>. Improvements and test cases are very welcome! Actually, there&#8217;s one disabled test right now that is not supported. If you can make it work, that would be pretty great!</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/bleach-html-sanitizer-and-auto-linker-for-django-344/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Upgrade Flash in Firefox</title>
		<link>http://coffeeonthekeyboard.com/upgrade-flash-in-firefox-289/</link>
		<comments>http://coffeeonthekeyboard.com/upgrade-flash-in-firefox-289/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 03:22:47 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[upgrade]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=289</guid>
		<description><![CDATA[If you upgraded Firefox lately, you might have seen a message on the start page urging you to upgrade Flash. As of yesterday, something like 12 million people had clicked through to upgrade. That&#8217;s a great number. However, when you got to the Adobe site, and clicked the &#8220;Agree and Install&#8221; button, instead just saving [...]]]></description>
			<content:encoded><![CDATA[<p>If you <a href="http://www.mozilla.com/">upgraded Firefox</a> lately, you might have seen a message on the start page <a href="http://www.mozilla.com/en-US/firefox/3.5.3/whatsnew/">urging you to upgrade Flash</a>. As of yesterday, <a href="http://blog.mozilla.com/metrics/2009/09/16/helping-people-upgrade-flash/">something like 12 million people</a> had clicked through to upgrade. That&#8217;s a great number.</p>
<p>However, when you got to the Adobe site, and clicked the &#8220;Agree and Install&#8221; button, instead just saving an installer file, you might have seen this:</p>
<p><img class="aligncenter size-full wp-image-290" title="update-flash-1" src="http://coffeeonthekeyboard.com/wp-content/uploads/2009/09/update-flash-1.png" alt="update-flash-1" width="402" height="166" />Right there? That&#8217;s enough to deter me from this whole process, so I can definitely understand if it scared you off. But this is an important update, a security update, so you need to do it.</p>
<p>Fortunately, it&#8217;s very easy to get around this annoying development in Flash. (Their hearts are in the right place, automatic updates, but their implementation leaves something to be desired. Of course, the Adobe Updater makes you quit Firefox to update Photoshop, so this clearly isn&#8217;t their strong suit.)</p>
<p>For starters, head to <a href="http://get.adobe.com/flashplayer" target="_blank">Adobe&#8217;s Get Flash</a> page. If you see that annoying bar, click on the [x] in the right corner:</p>
<p><img class="aligncenter size-full wp-image-291" title="update-flash-2" src="http://coffeeonthekeyboard.com/wp-content/uploads/2009/09/update-flash-2.png" alt="update-flash-2" width="191" height="114" />Now, more towards the middle of the page, look for a link that says &#8220;<a href="http://fpdownload.adobe.com/get/flashplayer/current/install_flash_player.exe">click here to download</a>.&#8221;</p>
<p><img class="aligncenter size-full wp-image-292" title="update-flash-3" src="http://coffeeonthekeyboard.com/wp-content/uploads/2009/09/update-flash-3.png" alt="update-flash-3" width="397" height="231" />That will start downloading the normal installer we&#8217;ve come to know and love. Yeah, you&#8217;ll still have to restart Firefox, but you were going to need to do that, anyway.</p>
<p>There you have it, avoiding Adobe&#8217;s strange new extra software and getting Flash up-to-date with the latest (really, <strong>really important</strong>) security fixes.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/upgrade-flash-in-firefox-289/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stop Supporting IE6</title>
		<link>http://coffeeonthekeyboard.com/stop-supporting-ie6-163/</link>
		<comments>http://coffeeonthekeyboard.com/stop-supporting-ie6-163/#comments</comments>
		<pubDate>Wed, 17 Dec 2008 18:04:35 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[enabling]]></category>
		<category><![CDATA[flaw]]></category>
		<category><![CDATA[Front-end]]></category>
		<category><![CDATA[out-of-date]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[Web 2.0]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=163</guid>
		<description><![CDATA[As a community, as a whole, web designers and developers need to stop supporting Internet Explorer 6. Now. Completely. I&#8217;ve been thinking a lot about browser compatibility as I&#8217;ve been working on Today&#8217;s Meet. My CSS is valid, but it doesn&#8217;t work quite right in IE6. The interface is completely JavaScript-based, and will only become [...]]]></description>
			<content:encoded><![CDATA[<p>As a community, as a whole, web designers and developers need to <strong>stop supporting Internet Explorer 6</strong>. Now. Completely.</p>
<p>I&#8217;ve been thinking a lot about browser compatibility as I&#8217;ve been working on <a href="http://todaysmeet.com/">Today&#8217;s Meet</a>. My CSS is valid, but it doesn&#8217;t work quite right in IE6. The interface is completely JavaScript-based, and will only become moreso in the future. How much time should I put into making it all work with IE6?</p>
<p><strong>None.<span id="more-163"></span><br />
</strong></p>
<p>I know lots of people, usually in government offices or schools, who are stuck with IE6. For some reason, their IT departments have neglected to update their systems for <em>over two years</em>.</p>
<p>(Sure, some of these systems are running <a href="http://www.betanews.com/article/Microsoft_No_IE7_for_Windows_2000/1117464807">Windows 2000</a>. This is a real minority at this point, though, and the rest have no excuse. If you&#8217;re running Windows 2000, and absolutely cannot afford to get new systems, get Firefox.)</p>
<p>I used to think I needed to support IE6 because this group is frighteningly large. But now I&#8217;ve come to realize—especially in the wake of <a href="http://voices.washingtonpost.com/securityfix/2008/12/microfot_emergency_patch_for_i.html?nav=rss_blog">this week&#8217;s news</a>—that by supporting IE6, all I&#8217;m really doing is enabling these lazy IT departments to keep running dangerously out-of-date software.</p>
<p>IE6 is the Vicodin to lazy IT&#8217;s <a href="http://en.wikipedia.org/wiki/Dr._Gregory_House#Character_biography">Dr. House</a>. As developers we&#8217;re Drs. <a href="http://en.wikipedia.org/wiki/James_Wilson_(House)">Wilson</a> and <a href="http://en.wikipedia.org/wiki/Lisa_Cuddy">Cuddy</a>. Just keep handing it out.</p>
<p>How up-to-date is the rest of the software on a system that (apparently) hasn&#8217;t run Windows Update in 2 years? What other major <a href="http://www.microsoft.com/security/malwareremove/default.mspx">security holes</a>, <a href="http://www.microsoft.com/enable/products/ie7/">accessibility issues</a>, and <a href="http://blogs.zdnet.com/web2explorer/?p=260">compatibility problems</a> would be solved by updating?</p>
<p>Not only is supporting IE6 annoying, it enables people to run software that is out-of-date and easily exploited. Are we really helping users, or are we just helping them get hacked?</p>
<p>So from now on, no more.</p>
<p>My personal projects will no longer support IE6. I won&#8217;t test in IE6.</p>
<p>IE7, Firefox 3, Safari 3, provisionally Opera (really, if it works in the first 3, it should work in Opera).  Keep your software up-to-date.</p>
<p>If you&#8217;re still using IE6, <a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">go get 7</a>. (Then don&#8217;t use it until after the Windows Update patch.)</p>
<p>If you can&#8217;t run updates, but can install software, <a href="http://www.mozilla.com/en-US/">go get Firefox</a>.</p>
<p>If you can&#8217;t do any of that, tell your IT department that running software 2 <em>years</em> out of date is unacceptable. Tell your boss to tell them. It&#8217;s a performance/security/accessibility/compatibility/etc issue.</p>
<p>And if you&#8217;re a developer, stop and think. Are you actually doing your visitors any good by supporting IE6? Or should you take all the time and effort you put into backwards compatibility and put it someplace more valuable?</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/stop-supporting-ie6-163/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Responsible SQL: How to Authenticate Users</title>
		<link>http://coffeeonthekeyboard.com/responsible-sql-how-to-authenticate-144/</link>
		<comments>http://coffeeonthekeyboard.com/responsible-sql-how-to-authenticate-144/#comments</comments>
		<pubDate>Sun, 09 Nov 2008 17:16:58 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[attack]]></category>
		<category><![CDATA[Back-end]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[injection]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=144</guid>
		<description><![CDATA[Most SQL-injection articles set a horrible example for young programmers. Here is a very typical &#8220;bad example&#8221; of why you need to escape user data before it goes into SQL queries: (ed. The symbol « is a line break that’s not in the real code.) $username = $_POST&#91;&#8216;username&#8217;&#93;; // username=admin $password = $_POST&#91;&#8216;password&#8217;&#93;; // password=&#8217; [...]]]></description>
			<content:encoded><![CDATA[<p>Most SQL-injection articles set a horrible example for young programmers.</p>
<p>Here is a very typical &#8220;bad example&#8221; of why you need to escape user data before it goes into SQL queries:</p>
<p>(ed. The symbol « is a line break that’s not in the real code.)</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$username</span> = <span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st0">&#8216;username&#8217;</span><span class="br0">&#93;</span>; <span class="co1">// username=admin</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$password</span> = <span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st0">&#8216;password&#8217;</span><span class="br0">&#93;</span>; <span class="co1">// password=&#8217; OR 1=1; &#8212; &#8216;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$user</span> = <span class="re0">$db</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM users WHERE «</span></div>
</li>
<li class="li2">
<div class="de2"><span class="st0"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; username=&#8217;$username&#8217; AND «</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; password=&#8217;$password&#8217; LIMIT 1;&quot;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>The point, of course, is that you must sanitize your user input, or else this person would run this query:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$user</span> = <span class="re0">$db</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM users WHERE «</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; username=&#8217;admin&#8217; AND «</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; password = &#8221; OR 1=1; &#8212; &#8216; LIMIT 1;&quot;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Which grants the sneaky user all your admin privileges. Other versions have nefarious users dropping your users or articles tables.</p>
<p>The problem is: this is the wrong way to authenticate users. These examples are written for beginners to understand the importance of sanitizing input, but they also provide a model to those beginners for how user authentication works. And it&#8217;s a very bad model.</p>
<p>This is a long one, more after the break.<span id="more-144"></span></p>
<p>The only upside to authenticating this way is that you don&#8217;t expose any information on failure, that is, if I&#8217;m trying to hijack someone&#8217;s account, I can&#8217;t tell the difference between an invalid user name and a valid user name with a bad password. That&#8217;s good, but there are good reasons not to do this at the database level.</p>
<p>The &#8220;correct&#8221; way is not much more complex. Basically:</p>
<ol>
<li>Look up the record with the <strong>username</strong> only.</li>
<li>Get the (hashed) password out of the database.</li>
<li>Hash the submitted password.</li>
<li>Compare the two hashes.</li>
</ol>
<p>This is really not very hard to implement. In PHP:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Check a password against the database</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @<a href="http://twitter.com/param">param</a> string $username The username to check</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* @<a href="http://twitter.com/param">param</a> string $password The (supposed) password</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @<a href="http://twitter.com/return">return</a> int 0=success, 1=bad username, 2=bad password</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> check_password <span class="br0">&#40;</span> <span class="re0">$username</span>, <span class="re0">$password</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$db</span> = <span class="kw2">new</span> mysqli<span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="co1">// we need to talk to the DB</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// the real_escape_string() function is much better</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// than add_slashes() for escaping MySQL database input</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$_username</span> = <span class="re0">$db</span>-&gt;<span class="me1">real_escape_string</span><span class="br0">&#40;</span><span class="re0">$username</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// I try to make my SQL queries as easy to read</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// as possible. (Not always very easy.)</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$result</span> = <span class="re0">$db</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT password &quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&quot;FROM users &quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&quot;WHERE username = &#8216;{$_username}&#8217; &quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&quot;LIMIT 1;&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// we&#8217;re assuming the query ran correctly</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// if we can&#8217;t return a row, then there&#8217;s no user with</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// that name</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> !<span class="re0">$user</span> = <span class="re0">$result</span>-&gt;<span class="me1">fetch_assoc</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">1</span>; <span class="co1">// return code for bad username</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// now, assuming the password was hashed with crypt()</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$user</span><span class="br0">&#91;</span><span class="st0">&#8216;password&#8217;</span><span class="br0">&#93;</span> != «</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/crypt"><span class="kw3">crypt</span></a><span class="br0">&#40;</span><span class="re0">$password</span>, <span class="re0">$user</span><span class="br0">&#91;</span><span class="st0">&#8216;password&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">2</span>; <span class="co1">// return code for bad password</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span>; <span class="co1">// return code for success</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>What&#8217;s going on here? Basically, we&#8217;re looking up the user by the username. If we don&#8217;t find a user, we throw out an error. If we do find a user, we re-encrypt the password they supplied, and check it against the encrypted password we already have. If they don&#8217;t match, we throw out an error. If they do, the user is allowed to log in.</p>
<p>There are two key differences between this method and the method so often espoused by tutorial writers:</p>
<ol>
<li>This method stores an encrypted password instead of plain text.</li>
<li>This method differentiates between bad usernames and bad passwords.</li>
</ol>
<p>#1 should be obvious. Never store an unencrypted password. It&#8217;s extremely dangerous: if someone ever gets a look at the table, they can just read the users&#8217; passwords—which may well be the same as their bank password (no it shouldn&#8217;t be, but it probably is). And it&#8217;s unnecessary. Every server-side language implements the MD5 hash, which is weak but works. Better options (like PHP&#8217;s <a onclick="window.open(this.href,'newwindow'); return false;" href="http://www.php.net/crypt">crypt()</a>) can use algorithms like Triple-DES, SHA1, Blowfish, or at least MD5 with a random salt.</p>
<p>But wait, #2, I said it was better <em>not</em> to distinguish between a bad username and a bad password, right? Well&#8230; yes, to the end user. In either case, I should display a message like &#8220;Bad username or password&#8221; to the person who tried to log in.</p>
<p>Internally, however, I want to know what happened. Is someone targetting known users, or just trying random combinations? How did they find real usernames? Where should I be improving security?</p>
<p>You&#8217;re also minimizing the number of user-submitted strings that get sent to the database. There are fewer opportunities for you to accidently allows an injection attack. If you have a policy on username syntax, you can keep yourself even safer by not talking to the database if the username is bad:</p>
<p>(I&#8217;ve omitted logging or real error-handling here. In a live version, I would probably wrap most of this in a <code><a onclick="window.open(this.href,'newwindow'); return false;" href="http://us2.php.net/manual/en/language.exceptions.php">try</a></code> block, throw one of three types of exceptions, and do some logging in the <code>catch</code> block.)</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// Usernames must start with a letter, and contain</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// only letters, numbers, underscores and dots, but</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// must not end with a dot or underscore.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$user_regex</span> = <span class="st0">&#8216;/[a-zA-Z][a-zA-Z0-9_<span class="es0">\.</span>]*[a-zA-Z0-9]/&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> <span class="br0">&#40;</span> <a href="http://www.php.net/preg_match"><span class="kw3">preg_match</span></a><span class="br0">&#40;</span><span class="re0">$user_regex</span>,<span class="re0">$username</span><span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// the username matches our allowed syntax</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$auth</span> = check_password<span class="br0">&#40;</span><span class="re0">$username</span>, <span class="re0">$password</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$auth</span> === <span class="nu0">0</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="co1">// the do_login() function is an exercise</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="co1">// to the reader</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; do_login<span class="br0">&#40;</span><span class="re0">$username</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// the username was bad, or the username/password</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// was wrong</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// die() is an overly simplistic choice, here.</span></div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/die"><span class="kw3">die</span></a><span class="br0">&#40;</span><span class="st0">&quot;Bad username or password.&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>Obviously we still escape the username, to make damn sure, but this gives us another place to get information. Did someone actually enter <code>'; DROP TABLE users; --</code> into our login form, or did they just mistype their password.</p>
<p>I&#8217;m going to end with a request: if you&#8217;re about to write a tutorial for beginners, please be aware of what you&#8217;re modeling in your examples. If you&#8217;re doing something you would never do, for the sake of simplicity or because it&#8217;s not the focus of the tutorial, point that out. Link to another tutorial or at least mention that it&#8217;s a bad way to do something.</p>
<p>Don&#8217;t send a quiet message that wrong is OK.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/responsible-sql-how-to-authenticate-144/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

