<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Tom Moertel's Weblog: Category security</title>
    <link>http://blog.moertel.com/articles/category/security</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Quality rants on programming theory and stuff geeks like</description>
    <item>
      <title>The Insecurity of Security Questions: Why I met my wife in CWmKryWzuxCSAnMDuIg.</title>
      <description>&lt;p&gt;Via &lt;a href="http://www.25hoursaday.com/weblog/2008/09/19/TheProblemWithEveryImplementationOfAForgotYourPasswordFeatureIveSeenOnline.aspx"&gt;Dare Obasanjo&amp;#8217;s blog&lt;/a&gt;, I learned
that the much-publicized cracking of Sarah Palin&amp;#8217;s Yahoo! email accounts was
accomplished by &lt;a href="http://blog.wired.com/27bstroke6/2008/09/palin-e-mail-ha.html"&gt;exploiting the weakness of &amp;#8220;security questions&amp;#8221;&lt;/a&gt;.  In short, all the attacker needed to do to convince Yahoo&amp;#8217;s computers that he was Palin was answer three questions as if he were Palin:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;What&amp;#8217;s your birthday?&lt;/li&gt;
		&lt;li&gt;What&amp;#8217;s your Zip code?&lt;/li&gt;
		&lt;li&gt;Where did you meet your spouse?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The attacker says he obtained the answers to these questions in less
than an hour. Everything he needed was already public knowledge, and
Google and Wikipedia made that knowledge easy to find.&lt;/p&gt;


	&lt;p&gt;And that&amp;#8217;s why when I sign up for web sites that ask me to provide baseline answers for those annoying security
questions, I claim that I met my spouse
in &lt;strong&gt;CWmKryWzuxCSAnMDuIg&lt;/strong&gt;.  What?  You&amp;#8217;ve never been there?  Well, that&amp;#8217;s not surprising.  It&amp;#8217;s not a real
place: it&amp;#8217;s a password, randomly generated, and remembered for me by
password-management software on my computer.&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s right.  Every time I&amp;#8217;m asked to establish my &amp;#8220;secret&amp;#8221; answer to a
security question, I generate a random string and use that.  Here&amp;#8217;s a
script I use:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl

use MIME::Base64;

open my $random, "/dev/urandom" 
    or die "can't open /dev/urandom";
my $bytes;
read $random, $bytes, 16;
close $random;

my $pw = encode_base64($bytes);
$pw =~ tr/A-Za-z0-9//cd;
print "$pw$/";
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Then I store the string in my password-management software, just in
case the web site asks me for it later.  Which should only happen if I
forget my primary password for that site.  Which should only happen if
I can&amp;#8217;t get into my password-management software.  Which should only happen if I&amp;#8217;m totally screwed, anyway, so what are the security questions buying me again?&lt;/p&gt;


	&lt;p&gt;In sum, if you care about your security, you&amp;#8217;re probably picking good passwords already. In that case, security questions can&amp;#8217;t help you, but they can harm you by making it easier for an attacker bypass your passwords. That&amp;#8217;s how the Palin-email cracker did it. So treat your answers to security questions as if they were passwords &amp;#8211; in effect, that&amp;#8217;s what they are.&lt;/p&gt;</description>
      <pubDate>Fri, 19 Sep 2008 11:06:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:511abe62-31c3-4d20-bdb8-8cfb827b2c61</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2008/09/19/the-insecurity-of-security-questions-why-i-met-my-wife-in-cwmkrywzuxcsanmduig</link>
      <category>security</category>
      <category>security</category>
      <category>passwords</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/816</trackback:ping>
    </item>
    <item>
      <title>A bright future: security and modern type systems</title>
      <description>&lt;p&gt;The &lt;a href="http://it.slashdot.org/it/07/08/12/1550254.shtml"&gt;recent defacement of the United Nations web
site&lt;/a&gt; is a prime
example of why we programmers shouldn&amp;#8217;t trust ourselves to write
secure code &amp;#8211; at least not without our computers&amp;#8217; help.  The U.N. web
site, according to Slashdot&amp;#8217;s coverage of the incident, was defaced by
way of a common, well-known attack: &lt;a href="http://en.wikipedia.org/wiki/SQL_injection"&gt;&lt;span class="caps"&gt;SQL&lt;/span&gt;
injection&lt;/a&gt;.  What&amp;#8217;s
interesting is that programmers can render this attack harmless by
employing simple, readily available programming tools such as
placeholders and prepared statements.  Why, then, are so many web sites,
including the UN site apparently, still vulnerable?&lt;/p&gt;


	&lt;p&gt;Some say it&amp;#8217;s because the programmers of these sites are incompetent,
but that argument ignores that programmers are
human, while the security tools we give them offer meaningful
protection only if wielded with inhuman perfection.  Having the tools
to plug security holes, even if the tools are simple to use and
readily available, is not enough to ensure that every single security
hole will be identified, let alone plugged.  Even the most experienced
programmer can be expected to overlook a hole now and then.
Unfortunately, one hole is all it takes.&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s because security is not like other software-quality challenges:
its costs are fundamentally asymmetric.  For the attacker, the bad
guy, the challenge is to find just a single exploitable hole.  For
us, the good guys, the challenge is to achieve perfection: to plug
&lt;em&gt;all&lt;/em&gt; of the holes in our code, every single one.  That&amp;#8217;s because
attackers, unlike regular users, can be expected to probe our code
until they find a hole to exploit.&lt;/p&gt;


	&lt;p&gt;How then do we ensure that we have plugged every single hole in our
code?  Testing isn&amp;#8217;t sufficient: we can easily overlook holes
when writing tests &amp;#8211; a perfectly human error.  We could supplement
testing with code reviews, painstakingly searching for remaining holes
while enforcing the use of hole-preventing best practices, but reviews
are expensive and, again, subject to human error.  A better approach,
both less costly and more reliable, is to delegate this burden to our
computers, which can do the job correctly, every single time.&lt;/p&gt;


	&lt;p&gt;This kind of delegation is possible today with modern static type systems.
For example, in &lt;a href="http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-strings-problem"&gt;A Type-Based Solution to the Strings
Problem&lt;/a&gt;,
I offered a tiny &amp;#8220;safe strings&amp;#8221; library for the &lt;a href="http://haskell.org/"&gt;Haskell programming
language&lt;/a&gt;.  The library takes advantage of
Haskell&amp;#8217;s powerful type system to detect unsafe string interactions at
compile time. If we faithfully build our code on top of the library, and our
code compiles without error, we can be assured that our code is
free &amp;#8211; completely free &amp;#8211; of &lt;span class="caps"&gt;SQL&lt;/span&gt;-injection (and &lt;a href="http://en.wikipedia.org/wiki/Cross-site_scripting"&gt;&lt;span class="caps"&gt;XSS&lt;/span&gt;&lt;/a&gt;) holes.&lt;/p&gt;


	&lt;p&gt;While this result is indeed quite beautiful, it certainly isn&amp;#8217;t novel.
Researchers have been proving interesting
properties via type systems for a long time.  As Oleg Kiselyov and Chung-chieh Shan pointed out in &lt;a href="http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-strings-problem#comment-204"&gt;a comment on my earlier article&lt;/a&gt;, the foundational idea is over three decades old.&lt;/p&gt;


	&lt;p&gt;More recently, Kiselyov and Shan have extended the
idea to guarantee more-interesting properties using a trusted kernel and types that represent
&lt;a href="http://okmij.org/ftp/papers/lightweight-static-capabilities.pdf"&gt;lightweight static
capabilities&lt;/a&gt;.
The kernel, which is small enough to be reasoned about and formally
verified, carefully hands out capabilities to untrusted application
code.  The untrusted code, in turn, presents the capabilities back to
the kernel to invoke operations, which, thanks to the kernel&amp;#8217;s
trustworthiness, are guaranteed to be safe.  (My safe-string library
can be seen as a trivial implementation of this programming style.)&lt;/p&gt;


	&lt;p&gt;When static type systems are used in this way, they don&amp;#8217;t merely catch
typos and bugs that good testing would have caught as a matter of
course, but offer programmers guarantees that would have been
impractical to obtain any other way.&lt;sup&gt;&lt;a href="#un-sql-fn1"&gt;1&lt;/a&gt;&lt;/sup&gt; If
you consider security important, you might bear this fact in mind when
choosing languages for your next project.&lt;/p&gt;


	&lt;p&gt;Going further, the security benefits of rich static type systems are only now
starting to trickle into mainstream industry.  As libraries like &amp;#8220;safe
strings&amp;#8221; and idioms like static capabilities become more familiar and
get woven into future generations of development frameworks, we can
expect marked improvements in the security and robustness of our
applications.&lt;/p&gt;


	&lt;p&gt;In the not-too-distant future, perhaps, we might look
back in amazement at the days when important security properties were
neither free nor guaranteed but expensive and uncertain, underwritten
only by the heroic efforts of individual programmers, struggling
against impossible odds to achieve inhuman perfection.&lt;/p&gt;


	&lt;p&gt;Then again, it sure took garbage collection a long time to catch on.&lt;/p&gt;


&lt;hr/&gt;

&lt;div class="footnote"&gt;

	&lt;p&gt;&lt;a name="un-sql-fn1"&gt;1.&lt;/a&gt; How, for example, could you eliminate the
possibility of &lt;span class="caps"&gt;SQL&lt;/span&gt;-injection and &lt;span class="caps"&gt;XSS&lt;/span&gt; holes via testing?&lt;/p&gt;


	&lt;p&gt;I suppose you could do it if you worked at
it hard enough. You could augment your string data
structures with run-time information about what they represent:
&lt;em&gt;this string represents &lt;span class="caps"&gt;SQL&lt;/span&gt;, this string represents plain-old
text&lt;/em&gt;, and so on.  Then you could redefine your string operations
and template interpolation systems to assert that their string inputs
were compatible.  Of course, if these assertions ever failed, they
would do so only at run time, when it would be too late to do anything
but die rather ungracefully.  So you would be forced to augment your
code-coverage tools to ensure that every string-path was covered
during testing.  That way you could catch all potential run-time
string failures &amp;#8211; indicating holes &amp;#8211; during testing and eliminate the
holes (and the subsequent need to fail at run time) before you
deployed your application for real.&lt;/p&gt;


	&lt;p&gt;So, yes, you could do it.  But to do so would require you, in effect,
to write a crude, single-purpose type system that checks types at test
time.  That says something, doesn&amp;#8217;t it?&lt;/p&gt;


&lt;/div&gt;</description>
      <pubDate>Wed, 15 Aug 2007 16:07:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:fd522245-d8b7-4270-814d-5237a26bb0b9</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/08/15/a-bright-future-security-and-modern-type-systems</link>
      <category>programming</category>
      <category>web development</category>
      <category>security</category>
      <category>types</category>
      <category>security</category>
      <category>capabilities</category>
      <category>safestrings</category>
      <category>sqlinjection</category>
      <category>xss</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/524</trackback:ping>
    </item>
    <item>
      <title>Don't let password recovery keep you from protecting your users</title>
      <description>&lt;p&gt;In 2006&amp;#8217;s most-read article on my blog, &lt;em&gt;&lt;a href="http://blog.moertel.com/articles/2006/12/15/never-store-passwords-in-a-database"&gt;Never store passwords in
a
database!&lt;/a&gt;&lt;/em&gt;,
I urged web programmers, unsurprisingly, not to store passwords
in their user databases.  I tried to persuade them to salt and hash
the passwords instead: store the salts and hashes in the database and
throw the passwords away.  The article, posted shortly after the
Reddit blog announced the &lt;a href="http://web.archive.org/web/20070109023445/http%3A//reddit.com/blog/theft"&gt;theft of its unprotected user
database&lt;/a&gt;, generated buckets of comments.
Reading over them today, I noticed something that I had missed
earlier.&lt;/p&gt;


	&lt;p&gt;It seems that a decent slice of programmers think that switching
to a salted-and-hashed password scheme implies giving up the ability to
assist users who have forgotten their passwords.  If the
passwords are irretrievably hashed away, the programmers reason, there&amp;#8217;s no way
to recover forgotten passwords and email them to stranded users.
Hence those users are screwed.&lt;/p&gt;


	&lt;p&gt;And that wrinkle, it might seem, is a good reason not to switch to a
salted-and-hashed password scheme.&lt;/p&gt;


	&lt;p&gt;But that wrinkle turns out to be imaginary.  Not being able to recover
an account&amp;#8217;s password does not mean that you can&amp;#8217;t
recover the account itself.  The password, after all, is not the thing
of value; the account is.  And, as we shall see, we can recover
an account without knowing its password.&lt;/p&gt;


	&lt;p&gt;Recall that the primary benefit of using a hash is that it is a
one-way operation.  Once you salt and hash a password, there is no
practical way to retrieve it.  That&amp;#8217;s what protects it from would-be
attackers.  But that also means &lt;em&gt;you&lt;/em&gt; can&amp;#8217;t get at it, either.
Thus sending password reminders to people who have forgotten their
passwords is no longer an option.&lt;/p&gt;


	&lt;p&gt;How, then, can you help your stranded users?  One method is to send
them account-recovery tokens, which you can think of as one-time,
special-purpose passwords.  (This method is suitable only if you
require no stronger authentication than knowing that your site&amp;#8217;s users own
the email addresses they claim to own.  This is the case for most &amp;#8220;low
security&amp;#8221; sites such as Slashdot, Reddit, and Digg, as
well as most blogging systems.)&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s how it works.  Say Joe has lost his password and can&amp;#8217;t log in
to your site. He clicks that button that says &amp;#8220;I&amp;#8217;ve lost my
password. Help me!&amp;#8221;  Now what?&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s what you do:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Generate a big, random, unique token and stuff it into Joe&amp;#8217;s account record in the database.  Stuff the current date and time in there, too.&lt;/li&gt;
		&lt;li&gt;Send an email to Joe, but instead of enclosing his password (which you can&amp;#8217;t recover), tell Joe to click on the enclosed account-recovery link, which includes the random token: &lt;code&gt;http://example.com/recover-account?token=pCIqq1unxntVqc8XtCXg&lt;/code&gt;.&lt;/li&gt;
		&lt;li&gt;Joe receives the email and clicks on the link, which sends his token to your site.&lt;/li&gt;
		&lt;li&gt;Look up the token in the user database.  Is it there?
	&lt;ol&gt;
	&lt;li&gt;No? Render a screen that says, &amp;#8220;Sorry, bub, that token is no longer valid.&amp;#8221;  Stop.&lt;/li&gt;
		&lt;li&gt;Yes? Excellent. Grab the user record associated with the token.  (It will, of course, be Joe&amp;#8217;s record.)&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Is the date and time stamp on that record more than a few hours old?
	&lt;ol&gt;
	&lt;li&gt;Yes? Render that screen that says, &amp;#8220;Sorry, bub, that token is no longer valid.&amp;#8221; Stop.&lt;/li&gt;
		&lt;li&gt;No? Congratulations.  Joe has effectively authenticated himself via his email address.&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Render a confirmation screen that explains the following to Joe:
	&lt;ol&gt;
	&lt;li&gt;His account password is going to be reset to the following random string: &lt;strong&gt;ocZodbew&lt;/strong&gt;. (Generate a new random string each time.)&lt;/li&gt;
		&lt;li&gt;If he likes the password, great.  If not, he can use the change-password feature immediately after the password is reset.&lt;/li&gt;
		&lt;li&gt;If he understands the above and wants to continue, he should confirm by clicking the big &amp;#8220;Reset My Account Password&amp;#8221; button.&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Joe clicks the button.&lt;/li&gt;
		&lt;li&gt;You, in response, do the following:
	&lt;ol&gt;
	&lt;li&gt;Delete the recovery token from Joe&amp;#8217;s user record in the database. (This prevents somebody from using the old token to steal his account, should, for example, Joe&amp;#8217;s email get stolen.)&lt;/li&gt;
		&lt;li&gt;Replace Joe&amp;#8217;s old password with the new, randomly generated password from above.  (You will, of course, use the salted-and-hashed method and &lt;em&gt;not&lt;/em&gt; store the new password itself.)&lt;/li&gt;
		&lt;li&gt;Log Joe in.&lt;/li&gt;
		&lt;li&gt;Render a screen saying, &amp;#8220;Joe, please don&amp;#8217;t forget that your new password is &lt;strong&gt;ocZodbew&lt;/strong&gt;.  If you would like to change it, just visit Change My Password in your account preferences [provide a link].  Otherwise, you&amp;#8217;re logged in and ready to go.  Enjoy the site!&amp;#8221; &lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;And you&amp;#8217;re done.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;The code required to make it happen is shorter than the explanation
above.  It&amp;#8217;s one of those easier-done-than-said things.&lt;/p&gt;


	&lt;p&gt;So, if concerns about account recovery have been holding you
back from protecting your users&amp;#8217; passwords, you need hold back no
longer.  It&amp;#8217;s time to &amp;#8220;do&amp;#8221; your due diligence.&lt;/p&gt;


&lt;div class="update"&gt;

	&lt;p&gt;&lt;strong&gt;Update 2007-09-10:&lt;/strong&gt; I made clear that the account-recovery method I
describe above is suitable only for low-security sites where
a valid email address is sufficient to authenticate users.&lt;/p&gt;


&lt;/div&gt;</description>
      <pubDate>Fri, 09 Feb 2007 15:36:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ddd87596-c734-4f36-996c-bc74a39e9dd3</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/02/09/dont-let-password-recovery-keep-you-from-protecting-your-users</link>
      <category>web development</category>
      <category>security</category>
      <category>security</category>
      <category>passwords</category>
      <category>salt</category>
      <category>hash</category>
      <category>database</category>
      <category>recovery</category>
      <category>risks</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/370</trackback:ping>
    </item>
    <item>
      <title>Never store passwords in a database!</title>
      <description>&lt;p&gt;Recently, the folks behind &lt;a href="http://reddit.com/"&gt;Reddit.com&lt;/a&gt; confessed
that &lt;a href="http://web.archive.org/web/20070109023445/http%3A//reddit.com/blog/theft"&gt;a backup copy of their database had been
stolen.&lt;/a&gt; Later, spez, one of the Reddit
developers, &lt;a href="http://reddit.com/info/usqe/comments/cuugl"&gt;confirmed&lt;/a&gt;
that the database contained password information for Reddit&amp;#8217;s users,
and that the information was stored as plain, unprotected text.
In other words, once the thief had the database, he had everyone&amp;#8217;s
passwords as well.&lt;/p&gt;


	&lt;p&gt;Had the folks at Reddit &lt;a href="http://en.wikipedia.org/wiki/Password_cracking#Salting"&gt;salted and
hashed&lt;/a&gt; the
passwords, the thief would now be in a very different situation.
Instead of holding all the keys to the kingdom, he would face the
prospect of a potentially expensive search for each and every user&amp;#8217;s
password he wanted to extract from the database.  The expense of the
search would likely have dissuaded him from making the attempt in
earnest, given how little exploitable value a Reddit account represents.  In
short, the passwords would have been secure, even though the database
had fallen into the thief&amp;#8217;s hands.&lt;/p&gt;


	&lt;p&gt;Why, then, didn&amp;#8217;t Reddit&amp;#8217;s programmers salt and hash the passwords
before storing them in their database?  Because, according to the
earlier post by spez, they wanted to be able to send forgotten
passwords to users via email.  It was a design decision: they
weighed the risks of having plain-as-day passwords in the database
against the convenience of being able to email users their forgotten
passwords and decided that, in the balance, convenience carried more
weight.  It&amp;#8217;s a decision they now regret.  (It&amp;#8217;s a doubly unfortunate
decision because &lt;a href="http://blog.moertel.com/articles/2007/02/09/dont-let-password-recovery-keep-you-from-protecting-your-users"&gt;you don&amp;#8217;t need to store passwords in your user database
in order to offer convenient account recovery&lt;/a&gt;.)&lt;/p&gt;


	&lt;p&gt;The reason I&amp;#8217;m writing about this event isn&amp;#8217;t to kick the
good folks at Reddit while they&amp;#8217;re down.  Rather, I&amp;#8217;m trying to make a point:&lt;/p&gt;


&lt;p style="padding-left: 2em; padding-right: 2em"&gt;&lt;strong&gt;If you are
storing passwords in a database, you are almost certainly making a
mistake.&lt;/strong&gt;&lt;/p&gt;

	&lt;p&gt;The guys at Reddit are known for being smart.  They thought they had a
good reason for storing passwords in their database.  They
were wrong.  If smart programmers can make this mistake, lots
of programmers can.  Do you think you have a good reason for storing
passwords in your database?  If so, you&amp;#8217;re probably wrong, too.&lt;/p&gt;


	&lt;p&gt;How can I be so sure?  Because, when it comes to web-app authentication,
cutting corners doesn&amp;#8217;t buy you anything. It doesn&amp;#8217;t save you coding time.
It doesn&amp;#8217;t give your users a better experience. All it does is weaken the security of your web application, needlessly putting your users, your employer, and yourself at  risk.&lt;/p&gt;


	&lt;p&gt;So please let me take this opportunity to ask if you
know of (or perhaps work on) any software systems that store passwords
as plain, unprotected text in a database.  If so, &lt;em&gt;fix your
software now&lt;/em&gt;:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Salt and hash each and every password (use an expensive hashing function such as bcrypt that was designed for password applications)&lt;/li&gt;
		&lt;li&gt;Store the salt and
hash &amp;#8211; not the password &amp;#8211; in your database. &lt;/li&gt;
		&lt;li&gt;Throw the password itself away.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You&amp;#8217;ll be glad you did.&lt;/p&gt;


&lt;div class="update"&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Minor edits for clarity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2007-02-13:&lt;/strong&gt; Salting and hashing does not get in the way of account recovery.  You do &lt;em&gt;not&lt;/em&gt; need to email users their forgotten passwords: there are other account-recovery options that are just as convenient but much more secure.  See &lt;a href="http://blog.moertel.com/articles/2007/02/09/dont-let-password-recovery-keep-you-from-protecting-your-users"&gt;Don&amp;#8217;t let password recovery keep you from protecting your users&lt;/a&gt; for more.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2007-10-03:&lt;/strong&gt; Revised text slightly to emphasize that there is no benefit to be had by implementing a weak password system, and therefore there is no reason &lt;em&gt;not&lt;/em&gt; to implement a secure system. Pointed more directly to bcrypt, too.
&lt;/div&gt;</description>
      <pubDate>Fri, 15 Dec 2006 13:25:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:547d5909-6007-46a3-ae22-ae1f8d348658</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/12/15/never-store-passwords-in-a-database</link>
      <category>web development</category>
      <category>security</category>
      <category>reddit</category>
      <category>security</category>
      <category>passwords</category>
      <category>salt</category>
      <category>hash</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/267</trackback:ping>
    </item>
  </channel>
</rss>
