<?xml version="1.0" encoding="utf-8" standalone="no"?><feed xmlns="http://www.w3.org/2005/Atom">
 <title type="text">Emerose Blog</title>
 <link href="http://www.emerose.com/blog/" hreflang="en" rel="alternate" type="text/html"/>
 <link href="http://www.emerose.com/blog/atom.xml" rel="self" type="application/atom+xml"/>
 <rights>Copyright (c) 2010, Emerose Advisory Services</rights>
 <updated>2011-03-16T22:59:54-07:00</updated>
 <id>http://www.emerose.com/blog</id>
 <author>
   <name>Sam Quigley</name>
   <email>quigley@emerose.com</email>
   <uri>http://www.emerose.com/~quigley/</uri>
 </author>
 
 <xhtml:meta content="noindex" name="robots" xmlns:xhtml="http://www.w3.org/1999/xhtml"/><entry>
   <title>Timing Attacks Explained</title>
   <link href="http://www.emerose.com//timing-attacks-explained.html" rel="alternate" type="text/html"/>
   <updated>2010-07-25T00:00:00-07:00</updated>
   <id>http://www.emerose.com//timing-attacks-explained</id>
   <content type="html">&lt;blockquote&gt;
&lt;p&gt;Ed. note: This post was originally written as part of the Security Awareness Program at &lt;a href='https://squareup.com'&gt;Square&lt;/a&gt;. If you find this stuff interesting &lt;a href='https://squareup.com/jobs'&gt;come join us&lt;/a&gt; — we’re working on lots of cool problems, and are growing fast. You can also &lt;a href='/contact'&gt;get in touch with me directly&lt;/a&gt; if you’d prefer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;I should also note that it took me a while to get this post up. For “this week”, please read “the week of July 13”. — sq&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update 9/3/2010&lt;/strong&gt; Note that this is just a blog post. If you have problems with timing attacks, then you have real problems — and should contact a professional. Don&amp;#8217;t assume that because you read this post, you can design a secure cryptosystem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id='timing_attacks_explained'&gt;Timing Attacks Explained&lt;/h1&gt;

&lt;p&gt;Probably the most interesting bit of security research that happened this week was the dropping of &lt;a href='http://lists.openid.net/pipermail/openid-security/2010-July/001156.html'&gt;this little bombshell&lt;/a&gt; by Taylor Nelson of &lt;a href='http://rootlabs.com/'&gt;Root Labs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every OpenID implementation I have checked this far has contained timing dependent compares in the HMAC verification, allowing a remote attacker to forge valid tokens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I want to walk through this issue, talking about what it means, how it happened, and what happened next. But first, some background is probably in order:&lt;/p&gt;

&lt;h2 id='openid'&gt;OpenID&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://openid.net/'&gt;OpenID&lt;/a&gt; is essentially a lightweight single-sign on system for the web. The idea is that you have one “identity” — often just your primary email address — and you use that whenever you sign into other websites. Instead of having to create and remember a password every time you sign up for a new website, those services can simply ask your “identity provider” (eg, gmail) to verify that you are who you say you are. OpenID is the protocol that the websites and identity providers speak in order to carry out this verification.&lt;/p&gt;

&lt;p&gt;As you might imagine, under the covers, the OpenID protocol involves passing a bunch of messages around between the identity provider and the web service. Some of these messages might say, in effect, “this user is who he says he is”. If an attacker could forge these messages, then she could create messages saying she is anyone she likes — thus totally destroying the security of the system.&lt;/p&gt;

&lt;h2 id='hmac'&gt;HMAC&lt;/h2&gt;

&lt;p&gt;To prevent forgery, OpenID uses, appropriately enough, &lt;a href='http://en.wikipedia.org/wiki/Message_authentication_code'&gt;Message Authentication Codes&lt;/a&gt; (sometimes called MACs or signatures). In particular, the standard calls for a &lt;a href='http://en.wikipedia.org/wiki/HMAC'&gt;keyed-hash message authentication code&lt;/a&gt; (“HMAC”) — but the details aren’t important for this story. The point is just that, effectively, these messages have signatures — long, seemingly-random strings of bytes — and only the identity provider and the website know how to calculate the signature.&lt;/p&gt;

&lt;h2 id='checking_signatures'&gt;Checking Signatures&lt;/h2&gt;

&lt;p&gt;The problem that Taylor pointed out is in how these signatures get checked. &lt;em&gt;All&lt;/em&gt; of the implementations he checked — in Java, Python, Ruby, etc — checked these signatures in the same, naive way. In pseudo-code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if (signature(message) == signature_bytes) 
    return true;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In English, that says something like: Compute the correct signature of the message, and compare it (using the “==”operation) to the signature that we received. If (and only if) they match, then the signature is correct.&lt;/p&gt;

&lt;p&gt;If you’re thinking that that seems correct, then you’re right — which is why all of the implementors wrote it that way. Unfortunately, in all of the languages in question, it only &lt;em&gt;seems&lt;/em&gt; right: there is a subtle bug under the surface.&lt;/p&gt;

&lt;h2 id='comparing_strings'&gt;Comparing Strings&lt;/h2&gt;

&lt;p&gt;In order to understand the problem, we need to look at the way that languages implement the “&lt;code&gt;==&lt;/code&gt;” operation. Say we have two strings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a = &amp;quot;ABCD&amp;quot;
b = &amp;quot;ABBA&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When we test the truth of the statement &lt;code&gt;a==b&lt;/code&gt;, almost every language runs through the same algorithm: First, look at the first character. If they’re the same, move on to the next step. If they’re different, stop now because we know the two strings are different. For the next step, do the same thing with the second character; and repeat until you get to the last character. If you get to the end without finding a difference, then you know the two strings are the same.&lt;/p&gt;

&lt;p&gt;In pseudo-code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;for (i = 0; i &amp;lt; a.length; i++) {
	if (a[i] != b[i])
		return false;
}
return true;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Astute readers will note one important check missing from the pseudo-code. I left it out for clarity; extra credit to whomever spots it first. No bonus points for smart-alecs who point out that this wrong because modern CPUs do this in hardware.)&lt;/p&gt;

&lt;p&gt;Applying this algorithm to our two strings, &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; above, we get:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Compare the first characters of each string. They’re the same — both “&lt;code&gt;A&lt;/code&gt;” — so we move on to the next step.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Compare the second characters. Again, they’re the same — both “&lt;code&gt;B&lt;/code&gt;” — so we move on to the next step.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Compare the third characters. This time, they’re different: the third character of &lt;code&gt;a&lt;/code&gt; is “&lt;code&gt;C&lt;/code&gt;”, while the third character of &lt;code&gt;b&lt;/code&gt; is “&lt;code&gt;B&lt;/code&gt;”. Since we know the strings are different, we can stop now.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id='the_problem'&gt;The Problem&lt;/h2&gt;

&lt;p&gt;The important point to note here is that the algorithm stops &lt;em&gt;as soon as we notice a difference&lt;/em&gt;. This is good, normally, because it means that we don’t waste time continuing to check the strings even after we know they differ. However, in the case of MACs, this optimization is fatal.&lt;/p&gt;

&lt;p&gt;Imagine that Alice has a website that uses OpenID, and Bob has an account on the site. Mallory, an attacker, wants to break into Bob’s account. In order to do this, she needs to forge a message that says she is Bob. Since messages are signed, this really means that she has to forge the signature for that message.&lt;/p&gt;

&lt;p&gt;Signatures are normally long strings of bytes, but for the purposes of this example, let’s assume they are short strings of upper-case letters from A-Z. Thus, even more concretely, what Mallory has to do is figure out what that ten-letter string is.&lt;/p&gt;

&lt;h2 id='the_attack'&gt;The Attack&lt;/h2&gt;

&lt;p&gt;Here is where the optimization problem comes in. Mallory knows that the first character of the signature is a letter from A to Z. To figure out which letter is correct, she can send each of the following signatures to the server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;AAAAAAAAAA
BAAAAAAAAA
CAAAAAAAAA
DAAAAAAAAA
...
XAAAAAAAAA
YAAAAAAAAA
ZAAAAAAAAA&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, it’s extremely unlikely that any of these is the correct signature for the message she wants to send. In fact, in 25 out of the 26 cases, the server only has to look at the first letter to know that the signature is wrong. But Mallory knows that, in exactly one of the 26 cases, the first letter will be correct, and the server will have to move on and compare the &lt;em&gt;second&lt;/em&gt; letter of her signature. For that one message, the server has to perform more work — and so the server will take slightly longer to return an error message. By timing how long it takes for the server to report an error, Mallory can detect which letter takes longer and thus which is the correct first letter. Armed with this knowledge, she can just repeat the trick and figure out the second letter, and then the third, etc etc.&lt;/p&gt;

&lt;p&gt;And that’s the attack. Mallory can use this trick to figure out, for a given message, what the correct signature is. And that means she can totally compromise the security of OpenID — in this case, by convincing Alice’s server that she is Bob.&lt;/p&gt;

&lt;h2 id='but'&gt;But&amp;#8230;&lt;/h2&gt;

&lt;p&gt;Many folks, when they understand the attack, respond by saying something like, “Ok, there may be a timing difference — but it’s very very small, and the Internet is very very big. There’s no way you could detect which signature takes longer!”&lt;/p&gt;

&lt;p&gt;Intuitively, this seems right. Given all the routers and proxies and whatnot on the Internet, there are a ton of random network-level delays that are much bigger than the delay introduced by one extra character comparison. For each message Mallory sends, this network jitter will outweigh any information about which signature took longer to process.&lt;/p&gt;

&lt;p&gt;But of course, Mallory isn’t limited to trying each signature once. She can try as many times as she likes — and by averaging results across a large enough data set, she can remove the effects of this jitter. This is the magic of statistics: &lt;em&gt;any&lt;/em&gt; difference can be observed, given enough measurements.&lt;/p&gt;

&lt;p&gt;In this case, &lt;a href='http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf'&gt;Crosby et al showed&lt;/a&gt; that a few tens of thousands of measurements is all it takes to time things with 15 microsecond accuracy over the Internet. (On a LAN, the same number of measurements can pinpoint timings to ~100 &lt;em&gt;nanoseconds&lt;/em&gt;.) The question of just how much precision Mallory needs in order to carry out her attack will depend on the language used to implement the server — but as an example, &lt;a href='http://www.cs.cmu.edu/~dbrumley/pubs/openssltiming.pdf'&gt;Dan Boneh and friends showed&lt;/a&gt; in 2003 that, due to a similar timing vulnerability in OpenSSL, a few million requests could reveal an entire 1024-bit SSL private key. More concretely, the reason that this issue in OpenID is being discussed now is that the authors at Root Labs are going to be presenting new results at Blackhat in a few weeks — results that, presumably, show how OpenID can be compromised within a reasonable number of requests by using this attack.&lt;/p&gt;

&lt;h2 id='the_fix'&gt;The Fix&lt;/h2&gt;

&lt;p&gt;The problem here is essentially that the timing of the server’s responses reveals information about the correct signature. The solution, then, is to ensure that the server takes the same amount of time to respond no matter which signature is sent. Remember that the implementation of &lt;code&gt;==&lt;/code&gt; in most languages stops checking the strings as soon as a difference is found. What we want is a comparison function that checks the whole string before reporting whether or not a difference was found. In pseudo-code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;match = true;
for (i = 0; i &amp;lt; a.length; i++) {
	if (a[i] != b[i])
		match := false;
}
return match;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is exactly the same as the previous &lt;code&gt;==&lt;/code&gt; definition, except that the return statement inside the for loop has been removed. Now, when a difference is detected, that will be noted — but the comparison will still continue through the rest of the string. Only once the entire string has been checked will the result be returned.&lt;/p&gt;

&lt;p&gt;This is a good solution, but the astute reader will note that the code that gets executed still depends on the equality of the strings. Two strings that differ only in one character will execute the “&lt;code&gt;match := false&lt;/code&gt;” line exactly once, while strings that differ in all 10 places will execute it 10 times, and strings that match exactly will execute it zero times. Even this kind of difference could conceivably be used to reveal information about the true signature; though it’s somewhat more complicated, the idiom for doing this kind of comparison is actually:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;match = 0;
for (i = 0; i &amp;lt; a.length; i++) {
	match = match or (a[i] xor b[i])
}
return match == 0;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here, “&lt;code&gt;or&lt;/code&gt;” and “&lt;code&gt;xor&lt;/code&gt;” should be taken as binary arithmetic operations, which don’t short-circuit — if that doesn’t make sense to you, don’t worry: this form does essentially the same thing as the last one. It iterates through the strings, noting every bit that differs between the two strings, and then checks at the end that no differences were noted. The difference is that, in this version, the operations that get executed don’t depend on the input in any way. No matter what the strings look like, the same &lt;code&gt;or&lt;/code&gt; and &lt;code&gt;xor&lt;/code&gt; operations are performed. This version is totally immune to any sort of timing attack.&lt;/p&gt;

&lt;h2 id='the_lesson'&gt;The Lesson&lt;/h2&gt;

&lt;p&gt;This kind of timing vulnerability is &lt;em&gt;really&lt;/em&gt; common. Remember that every OpenID implementation that the Root Labs guys checked had this flaw, even though they mostly written by separate developers. The same problem was found in &lt;a href='http://groups.google.com/group/oauth/browse_thread/thread/f3e9ec6c3aa0fe1a'&gt;some OAuth implementations&lt;/a&gt;, in &lt;a href='http://codahale.com/a-lesson-in-timing-attacks/'&gt;Java 6’s &lt;code&gt;MessageDigest.isEqual&lt;/code&gt;&lt;/a&gt; method, in &lt;a href='http://groups.google.com/group/rubyonrails-security/browse_thread/thread/da57f883530352ee'&gt;Rails’ cookie-based session store&lt;/a&gt;, and &lt;a href='http://rdist.root.org/2009/05/28/timing-attack-in-google-keyczar-library/'&gt;all kinds of other places&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The lesson to learn here is emphatically not that cryptography is magic, or that developers shouldn’t bother trying to understand it. These issues are tricky, to be sure, and some security “experts” recommend against developers ever touching crypto code because of the possibility of error. But this kind of thinking &lt;a href='http://www.peereboom.us/assl/assl/html/openssl.html'&gt;leads to terrible code&lt;/a&gt;, as talented developers just end up neglecting the code in question. (It’s even worse when those same &lt;a href='http://www.links.org/?p=328'&gt;“experts” lash out at folks who try to improve the situation&lt;/a&gt;, blaming other people for their own code-rot… but I digress.)&lt;/p&gt;

&lt;p&gt;Instead, I think the lesson here is twofold. First, this stuff is subtle — but once you understand what’s going on, it’s not &lt;em&gt;that&lt;/em&gt; hard to figure out. I hope that the explanation above made sense (let me know if not!), but even if I butchered the delivery, I promise you that it’s not actually rocket science. (Figuring out that timing attacks are possible in the first place is certainly pretty hard, as is finding reliable ways to exploit them. But defending against them is a lot easier.)&lt;/p&gt;

&lt;p&gt;Second, it’s good to note that this particular flaw — comparing secret strings using simple &lt;code&gt;==&lt;/code&gt; operations — is really common, so it’s wise to understand it and keep an eye out for it. On the one hand, those who do not comprehend the bugs of the past are &lt;a href='http://github.com/rails/rails/commit/8b05c5207dd5757d55d0c384740db289e6bd5415'&gt;condemned to repeat them&lt;/a&gt;; on the other, as long as we can learn from our mistakes and the mistakes of others, we’ll be in great shape.&lt;/p&gt;

&lt;h2 id='fin'&gt;FIN&lt;/h2&gt;</content>
   <author>
     <name>Sam Quigley</name>
     <email>quigley@emerose.com</email>
     <uri>http://www.emerose.com/~quigley/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Security Answer of the Week, Websec Advice Edition — Part II</title>
   <link href="http://www.emerose.com//websec-advice-2-passwords.html" rel="alternate" type="text/html"/>
   <updated>2010-02-06T00:00:00-08:00</updated>
   <id>http://www.emerose.com//websec-advice-2-passwords</id>
   <content type="html">&lt;p&gt;(&lt;strong&gt;&lt;a href='/2010/02/06/websec-advice-1-intro'&gt;Continued from part 1…&lt;/a&gt;&lt;/strong&gt;)&lt;/p&gt;

&lt;h3 id='a_beginning_passwords'&gt;A beginning: Passwords&lt;/h3&gt;

&lt;p&gt;Our journey begins not, as one might surmise, with slide 0 or slide 1. Not, in other words, at the beginning — for the beginning is uncontroversial. No, dear reader, we shall not be wasting any more time than has already been lost. Instead, we begin with slide 14 — a slide with the unassuming title:&lt;/p&gt;

&lt;h4 id='plaintext_passwords_iv_fix'&gt;Plaintext Passwords IV Fix&lt;/h4&gt;

&lt;p&gt;We meet up with our intrepid explorers as they are recovering from “Plaintext Passwords IV” — which is to say, as they learn that One Should Hash Passwords With A Random Salt. As we said, uncontroversial — this is indeed good advice, consistent with all that is good and right with the world.&lt;/p&gt;

&lt;p&gt;But our protagonists were not satisfied. No, when they gazed at The Solution, they did not see the harmony and beauty of this answer. Instead, they saw only darkness and destruction — and it is into that vision that we too must now peer:&lt;/p&gt;
&lt;script src='http://gist.github.com/289455.js?file=Plaintext+Passwords+IV+Fix.php'&gt;&amp;nbsp;&lt;/script&gt;
&lt;p&gt;But lo!, the good &lt;a href='http://footle.org/' title='footle.org'&gt;Mr. Brad Greenlee&lt;/a&gt; cried out, this is&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;only using 4 chars of the salt for no clear reason, and with the salt limited to hex digits, the salt-space is even smaller (65536 possible values)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I believe PHP&amp;#8217;s &lt;code&gt;rand()&lt;/code&gt; isn&amp;#8217;t a very good PRNG. &lt;code&gt;mt_rand()&lt;/code&gt; is better…although it would be better to have a salt space that is greater than just &lt;code&gt;getrandmax()&lt;/code&gt;/&lt;code&gt;mt_getrandmax()&lt;/code&gt; values.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All reasonable points. It’s unclear why the author has chosen to restrict the salt to 16 bits: &lt;em&gt;ceteris paribus&lt;/em&gt;, the larger the salt keyspace, the better.&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt; And PHP’s &lt;a href='http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/standard/rand.c?view=markup' title='rand.c from the PHP source'&gt;random-number generation code&lt;/a&gt; is, frankly, utterly broken.&lt;sup id='fnref:2'&gt;&lt;a href='#fn:2' rel='footnote'&gt;2&lt;/a&gt;&lt;/sup&gt; On the other hand, if what we’re worrried about is precomputation (“rainbow table”) attacks, even these few bits of entropy will still increase the amount of work necessary by a factor of 2^16. Not enough to stop a determined attacker, perhaps, but probably enough of a hassle to dissuade more casual bad guys. For this observation, the intrepid Mr. Greenlee found himself &lt;strong&gt;2 points&lt;/strong&gt; closer to enlightenment.&lt;/p&gt;

&lt;p&gt;But Brad was not sated. He peered still closer at the Proposed Solution, and was horrified to find a still deeper problem, just below the surface, peering back.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The password hash could be improved by using something more compute-intensive, like bcrypt&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;he cried; and this time, his voice was joined by a fellow traveler, a certain &lt;a href='http://codahale.com' title='codahale.com'&gt;Coda Hale&lt;/a&gt;, who &lt;a href='http://twitter.com/coda/statuses/8011927766' title='Coda’s tweet'&gt;cried out&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;MD5 instead of bcrypt&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;somewhat more cryptically.&lt;/p&gt;

&lt;p&gt;Truly it was this flaw, much more serious than the last, that drew our heroes’ attention to the cracks in the façade of Web Security Advice they had been faced with. For this was no minor quibble about how threat models and the determination of our attackers. This was a serious threat to the author’s vision of a peaceful and harmonious world. Computing an MD5 hash on ordinary hardware, it turns out, is fast — really, really fast. &lt;a href='http://www.elcomsoft.com/lhc.html' title='Lightning Hash Cracker from Elcomsoft'&gt;Hundreds of millions of hashes per second&lt;/a&gt; fast. At these speeds, rainbow tables are no longer interesting: an attacker can &lt;em&gt;easily&lt;/em&gt; brute-force just about any password in a trivial amount of time, salt or no salt.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://codahale.com/how-to-safely-store-a-password/'&gt;The correct answer here is simple&lt;/a&gt;: use &lt;a href='http://www.usenix.org/events/usenix99/provos.html' title='Provos and Mazières: A Future-Adaptable Password Scheme'&gt;bcrypt&lt;/a&gt;, &lt;a href='http://www.tarsnap.com/scrypt.html' title='The scrypt key derivation function and encryption utility'&gt;scrypt&lt;/a&gt;, or &lt;a href='http://en.wikipedia.org/wiki/PBKDF2' title='Password-Based Key Derivation Function 2 at Wikipedia'&gt;PBKDF2&lt;/a&gt; — something that has been &lt;em&gt;designed&lt;/em&gt; to be slow and hard to compute. A simple MD5 hash does not come anywhere near sufficiency these days. This realization, no matter how depressing, nevertheless earned our two protagonists &lt;strong&gt;10 further points&lt;/strong&gt; each.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continued in part three, to be posted shortly…&lt;/strong&gt;&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;Up to the hash size, of course.&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:2'&gt;
&lt;p&gt;By default, the only source of entropy PHP has is the process ID and a couple of timestamps. This weakness, and the fact that neither &lt;code&gt;rand()&lt;/code&gt; nor &lt;code&gt;mt_rand()&lt;/code&gt; is anything like a &lt;a href='http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator' title='Wikipedia: Cryptographically Secure Pseudorandom Number Generator'&gt;cryptographically-secure RNG&lt;/a&gt;, has already been responsible for a &lt;a href='http://samy.pl/phpwn/' title='Samy Kamkar’s ‘phpwn’ attack'&gt;very impressive break of PHP session IDs&lt;/a&gt;. The PHP project’s &lt;a href='http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/standard/lcg.c?r1=293253&amp;amp;r2=293252&amp;amp;pathrev=293253' title='r293252 from the PHP SVN repository'&gt;supposed fix&lt;/a&gt; for the problem does essentially nothing, adding at most a bit or two of entropy to the mix; most troubling, however, is the primary author’s &lt;a href='http://twitter.com/rasmus/status/7539461498' title='One of many misguided Tweets on the subject'&gt;rather stubborn insistence that everything is OK&lt;/a&gt; when these issues were reported. If you are forced to use PHP, for whatever reason, I recommend setting &lt;code&gt;session.entropy_file=&amp;quot;/dev/urandom&amp;quot;&lt;/code&gt; and &lt;code&gt;session.entropy_length=&amp;quot;128&amp;quot;&lt;/code&gt; in &lt;code&gt;php.ini&lt;/code&gt;, as well as reading directly from &lt;code&gt;/dev/urandom&lt;/code&gt; rather than calling any of the &lt;code&gt;rand()&lt;/code&gt; or &lt;code&gt;mt_rand()&lt;/code&gt; functions.&lt;/p&gt;
&lt;a href='#fnref:2' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
   <author>
     <name>Sam Quigley</name>
     <email>quigley@emerose.com</email>
     <uri>http://www.emerose.com/~quigley/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Security Answer of the Week, Websec Advice Edition — Part I</title>
   <link href="http://www.emerose.com//websec-advice-1-intro.html" rel="alternate" type="text/html"/>
   <updated>2010-02-06T00:00:00-08:00</updated>
   <id>http://www.emerose.com//websec-advice-1-intro</id>
   <content type="html">&lt;p&gt;Good evening, and welcome to yet another edition of &lt;em&gt;Security Question of the Week&lt;/em&gt;. I hope you are well. This week, we have a good deal of ground to cover, for I intend to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prove conclusively that there’s nothing “weekly” about the “Security Question of the Week”&lt;/li&gt;

&lt;li&gt;Force you to think about PHP for a minute or two&lt;/li&gt;

&lt;li&gt;Keep beating the a-hash-function-is-not-a-message-authenticator horse&lt;/li&gt;

&lt;li&gt;And yes, quite a bit more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How very exciting. One can hardly wait, can one? But unfortunately wait you must, as we are required first to pause for reflection on the question at hand:&lt;/p&gt;

&lt;h3 id='a_reprise'&gt;A reprise&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Like last week’s question, this week’s is another “spot the bad advice” question — this time, ripped &lt;a href='http://news.ycombinator.com/item?id=1045392' title='The ‘Hacker News’ headlines, that is.'&gt;straight from the headlines&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href='http://6.470.scripts.mit.edu/lectures/security/html/all.html' title='Security in Web Applications slides'&gt;“Security in Web Applications”&lt;/a&gt; are the slides from a presentation on web security given a couple weeks ago as part of MIT’s &lt;a href='http://6.470.scripts.mit.edu/index.php' title='MIT’s 6.470: Web Programming Competition'&gt;6.470 Web Programming Competition&lt;/a&gt;. There is a lot of good advice in there — but unfortunately, there are also some reasonably significant problems. Spot them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;As always, the best answer(s) win the prize. Send them to me via email or on twitter — bonus points for impact, obscurity, irony, sangfroid, schadenfreude, and/or bonhomie. I’ll post the results here at the end of the week.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It seems like ages ago, doesn’t it, since that question &lt;a href='http://www.emerose.com/2010/01/18/sqotw-more-advice.html' title='Security Question of the Week, Websec Advice Edition'&gt;was posted&lt;/a&gt; here? And ages it has indeed been. Think back upon that those halcyon days, if you would: it was a simpler time. We hadn’t yet even begun to ask whether the iPad would save, destroy, or indeed merely tangentially affect our proud “hacker culture.” We didn’t yet know the state of our union. Some poor souls may even have thought that answers to this very Security Question of the Week would be posted “at the end of the week.” A time, indeed, of innocence.&lt;/p&gt;

&lt;h3 id='a_search_for_answers'&gt;A search for answers&lt;/h3&gt;

&lt;p&gt;It was in the context of those prelapsarian days, then, that our story begins. For that was when our gladiators surveyed the landscape, full of possibility, and their eyes alighted on some Advice — yea, some Advice of a Web Security nature; of undetermined providence but indubitable importance; and having a slidular nature. Advice, in other words, titled &lt;a href='http://6.470.scripts.mit.edu/lectures/security/html/all.html' title='Security in Web Applications slides'&gt;Security in Web Applications&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And verily, it was whilst reviewing these slides, that our heroes bit of that forbidden fruit. For they began to note the imperfections and flaws contained therein. They saw evidence — incontrovertible evidence — that the world was not as had been taught them. Flaws that no preëstablished harmony could account for; that no watchmaker God could be the author of; whose mere possibility implied a necessary truth about our world too horrible to comprehend. And the scales fell from their eyes.&lt;/p&gt;

&lt;p&gt;Yes, gentle reader, it is on that very journey that I propose to take you now. It will be a journey of discovery and enlightenment, joyous in some respects, certainly — but it shall also be a journey of disappointment and sorrow, for at the end of it we shall find ourselves in a world of suspicion and fear, where random slide decks found on the Internet cannot be trusted, where every webapp is vulnerable until proven otherwise, and where even the best and brightest amongst us find their work — the fruit of their most heartfelt, helpfully meant labors — teased apart and nitpicked to shreds on some dude’s website. This terrible journey will have but one consolation: the knowledge that it is inevitable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href='/2010/02/06/websec-advice-2-passwords'&gt;Continued in part two…&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</content>
   <author>
     <name>Sam Quigley</name>
     <email>quigley@emerose.com</email>
     <uri>http://www.emerose.com/~quigley/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Links!, Feb 6 Edition</title>
   <link href="http://www.emerose.com//links.html" rel="alternate" type="text/html"/>
   <updated>2010-02-06T00:00:00-08:00</updated>
   <id>http://www.emerose.com//links</id>
   <content type="html">&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href='http://nomoreroot.blogspot.com/2010/01/little-bug-in-safari-and-google-chrome.html'&gt;No More Root: Little bug in Safari and Google Chrome&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice trick for stealing URL-based session IDs or CSRF tokens: Put a webapp URL in a CSS &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tag, and then just use JS to wait a second or two and read &lt;code&gt;document.styleSheets[0].href&lt;/code&gt;. Tada.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://babelstone.blogspot.com/2009/11/whats-new-in-unicode-60.html'&gt;What&amp;#8217;s new in Unicode 6.0?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An interesting look at some of the politics behind the latest version of the Unicode standard:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unicode 6.0 includes some of the most controversial additions to the standard for a long time. In particular, the addition of a large set of characters corresponding to Japanese Emoji 絵文字 used on mobile phones has been the cause of much heated debate…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://igoro.com/archive/gallery-of-processor-cache-effects/'&gt;Igor Ostrovsky: Gallery of Processor Cache Effects&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In this blog post, I will use code samples to illustrate various aspects of how caches work, and what is the impact on the performance of real-world programs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A short article discussing the effects of processor caches. Includes some very nice graphs.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://www.nytimes.com/2010/02/02/business/global/02hacker.html?pagewanted=all'&gt;NYTimes: In China Underworld, Hacking for Fun and Profit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Short profile of a hacker in China:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Majia, a soft-spoken college graduate in his early 20s, is a cyberthief. He operates secretly and illegally, as part of a community of hackers who exploit flaws in computer software to break into Web sites, steal valuable data and sell it for a profit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://www.avertlabs.com/research/blog/index.php/2010/02/02/hackers-disrupt-european-co2-market/'&gt;McAfee Labs Blog: Hackers Disrupt European CO₂ Market&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In recent weeks, various cybercrime attacks have disrupted the computer systems that allow nations to manage their national greenhouse-gas emissions quotas and their possession of carbon assets according to international agreements (the Kyoto Protocol and the European system). One quota is the right to emit the equivalent of one ton of carbon dioxide during a specified period.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Short article discussing recent attacks on the European carbon trading market. Interestingly, one of the vectors seems to be VAT arbitrage: attackers buy and then resell carbon credits, collecting VAT on the sale but never paying VAT on the purchase. Similar to affiliate marketing fraud.&lt;/p&gt;

&lt;p&gt;The close of the article — “OMG APT!” — is pretty tedious, though. I suspect we’re going to se a lot of this FUD in the near future.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://www.nytimes.com/2010/02/03/us/politics/03intel.html?hp'&gt;NYTimes: Intelligence Chief Says Cyberattack Threat Is Growing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A cyber article from the cyber NYT about how “malicious cyber activity” cyber threatens our cyber nation. Apparently, the cyber risk of a cyber Pearl Harbor has never cyber been cyber bigger.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content>
   <author>
     <name>Sam Quigley</name>
     <email>quigley@emerose.com</email>
     <uri>http://www.emerose.com/~quigley/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Security Question of the Week, Websec Advice Edition</title>
   <link href="http://www.emerose.com//sqotw-more-advice.html" rel="alternate" type="text/html"/>
   <updated>2010-01-18T00:00:00-08:00</updated>
   <id>http://www.emerose.com//sqotw-more-advice</id>
   <content type="html">&lt;h3 id='the_question'&gt;The question&lt;/h3&gt;

&lt;p&gt;Like last week’s question, this week’s is another “spot the bad advice” question — this time, ripped &lt;a href='http://news.ycombinator.com/item?id=1045392' title='The ‘Hacker News’ headlines, that is.'&gt;straight from the headlines&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://6.470.scripts.mit.edu/lectures/security/html/all.html' title='Security in Web Applications slides'&gt;“Security in Web Applications”&lt;/a&gt; are the slides from a presentation on web security given a couple weeks ago as part of MIT’s &lt;a href='http://6.470.scripts.mit.edu/index.php' title='MIT’s 6.470: Web Programming Competition'&gt;6.470 Web Programming Competition&lt;/a&gt;. There is a lot of good advice in there — but unfortunately, there are also some reasonably significant problems. Spot them.&lt;/p&gt;

&lt;p&gt;As always, the best answer(s) win the prize. Send them to me &lt;a href='mailto:quigley@emerose.com'&gt;via email&lt;/a&gt; or &lt;a href='http://twitter.com/emerose' title='emerose on Twitter'&gt;on twitter&lt;/a&gt; — bonus points for impact, obscurity, irony, sangfroid, schadenfreude, and/or bonhomie. I’ll post the results here at the end of the week.&lt;/p&gt;</content>
   <author>
     <name>Sam Quigley</name>
     <email>quigley@emerose.com</email>
     <uri>http://www.emerose.com/~quigley/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Security Question of the Week, 1/8/10 Edition</title>
   <link href="http://www.emerose.com//sqotw-owasp-storage.html" rel="alternate" type="text/html"/>
   <updated>2010-01-08T00:00:00-08:00</updated>
   <id>http://www.emerose.com//sqotw-owasp-storage</id>
   <content type="html">&lt;p&gt;That’s right folks! It’s time for another installment of Security Question of the Week&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;! This week’s edition: &lt;a href='http://www.securityninja.co.uk/secure-storage-using-the-owasp-esapi' title='Security Ninja: Secure Storage using the OWASP ESAPI'&gt;an exciting blog post&lt;/a&gt; about the OWASP &lt;a href='http://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API' title='Enterprise Security API page at the OWASP Tools Project'&gt;&lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt;&lt;/a&gt; secure storage API! Yay!&lt;/p&gt;

&lt;p&gt;&lt;a href='http://twitter.com/emerose/status/7527677907' title='The fateful tweet'&gt;&lt;img src='/files/2010/01/12/sqotw.png' alt='Security Question of the Week, vol whatever: Whats wrong with this advice? http://bit.ly/586Xcy Best answer(s) win the prize.' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those of you playing along at home, that link &lt;a href='http://www.securityninja.co.uk/secure-storage-using-the-owasp-esapi' title='Security Ninja: Secure Storage using the OWASP ESAPI'&gt;goes here&lt;/a&gt; — to a post titled &lt;a href='http://www.securityninja.co.uk/secure-storage-using-the-owasp-esapi' title='Security Ninja: Secure Storage using the OWASP ESAPI'&gt;Secure Storage using the OWASP &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt;&lt;/a&gt; at the &lt;a href='http://www.securityninja.co.uk/home/' title='Security Ninja homepage'&gt;Security Ninja blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='disclaimer'&gt;Disclaimer&lt;/h3&gt;

&lt;p&gt;So, before we begin, it’s worth being nice and pointing out that these criticisms are meant to be taken in a constructive spirit. In particular, I think we all ought to agree that the &lt;a href='http://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API' title='Enterprise Security API page at the OWASP Tools Project'&gt;&lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt;&lt;/a&gt; project is a &lt;a href='http://www.owasp.org/images/8/81/Esapi-datasheet.pdf' title='Introduction to the ESAPI (pdf'&gt;great idea whose time has come&lt;/a&gt; — and that posts like Security Ninja’s, which help programmers figure out how to use &lt;a href='http://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API' title='Enterprise Security API page at the OWASP Tools Project'&gt;&lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt;&lt;/a&gt; in the real world, are equally necessary. I should also mention that there are almost certainly mistakes in what follows; if you have anything to add or correct, &lt;a href='http://www.emerose.com/contact' title='Contact us'&gt;let me know&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That said, security is hard, and I think there are a bunch of problems in the API — and Security Ninja’s post exemplifies a few of them quite nicely. So…&lt;/p&gt;

&lt;h3 id='ok_lets_go'&gt;OK, Let’s Go!&lt;/h3&gt;

&lt;p&gt;Let’s meet our first contestant, &lt;a href='http://radar.oreilly.com/marc/' title='Marc’s profile at O’Reilly Radar'&gt;Marc&lt;/a&gt;. Welcome, Marc! Marc &lt;a href='http://twitter.com/precipice/status/7528340826'&gt;tweets&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://twitter.com/precipice/status/7528340826'&gt;&lt;img src='/files/2010/01/12/precipice.png' alt='@emerose secure access to the master salt? 2 salts? write your own hashing code? hide configuration file naming the algo? overuse of ninja?' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Convincing answers! But whatever could they mean? Let’s investigate.&lt;/p&gt;

&lt;h4 id='secure_access_to_the_master_salt'&gt;“Secure access to the master salt”&lt;/h4&gt;

&lt;p&gt;In the blog post, Security Ninja warns us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I cannot stress the importance of making this [master salt] a sufficiently strong/random value and securing access to the value itself wherever you choose to store it”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; &lt;a href='http://owasp-esapi-java.googlecode.com/svn/trunk_doc/1.4/org/owasp/esapi/Encryptor.html#hash(java.lang.String,%20java.lang.String)' title='org.owasp.esapi.Encryptor.hash Javadocs'&gt;hash function JavaDoc&lt;/a&gt; also seems to suggest that salts need to be secret:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Some good choices for a salt might be … [a] string that is known to the application but not to an attacker.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And, finally, the &lt;a href='http://en.wikipedia.org/wiki/Salt_%28cryptography%29' title='Salt (cryptography'&gt;Wikipedia article on salts&lt;/a&gt; agrees:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“For best security, the salt value is kept secret, separate from the password database. This provides an advantage when a database is stolen, but the salt is not. To determine a password from a stolen hash, an attacker cannot simply try common passwords (such as English language words or names). Rather, they must calculate the hashes of random characters (at least for the portion of the input they know is the salt), which is much slower.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To which I say: &lt;strong&gt;hogwash&lt;/strong&gt;. Total nonsense. Wrong.&lt;/p&gt;

&lt;p&gt;The point of a salt is not secrecy. The point is to defend against precomputation (“&lt;a href='http://en.wikipedia.org/wiki/Rainbow_table' title='Rainbow table page on Wikipedia'&gt;rainbow table&lt;/a&gt;“) attacks. Salts achieve this by introducing a bit of extra variance into the mix: if an attacker wants to compute the hash values for the 1,000 most common passwords, and no salt has been included, then she only needs to compute 1,000 hashes. If there’s a 1 bit salt included, though, her work doubles: she’ll have to compute 1,000 hashes to cover the case where the salt is 0, and another 1,000 to cover the case where the salt is 1. With a 2-bit salt, 4,000 hashes are required; with a 1-byte salt, 256,000 hashes are required, and so on. &lt;strong&gt;A salt even a few bytes long will make computing (and storing) rainbow tables literally millions of times harder.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But it’s worth pointing out that &lt;strong&gt;salts have this property whether or not the salt is a secret&lt;/strong&gt;. It really doesn’t matter if the attacker knows what the salts are: so long as the salt value varies independently from password to password, computing a general-purpose rainbow table will still require computing a hash for every possible combination of candidate password and possible salt. In fact it’s important, in at least an abstract sense, that the system &lt;em&gt;not&lt;/em&gt; depend on the secrecy of salts: &lt;a href='http://www.petitcolas.net/fabien/kerckhoffs/' title='Partial Translation of La Cryptographie Militaire'&gt;Kerckhoffs’ principle&lt;/a&gt; reminds us that &lt;strong&gt;the security of the system should reside only in the key&lt;/strong&gt; (password), and that the system should not be impacted if the enemy learns the details. Security through obscurity and all that.&lt;/p&gt;

&lt;p&gt;As long as we’re talking about this, it might be interesting to point out that most real-world cryptosystems make no effort to protect password salts. UNIX shadow password files embed the salt in the hash string, for example, and &lt;a href='http://en.wikipedia.org/wiki/Wi-Fi_Protected_Access#Security_in_pre-shared_key_mode' title='Wi-Fi Protected Access on Wikipedia'&gt;WPA-PSK&lt;/a&gt;, the fancy new(-ish) WiFi security standard, &lt;a href='http://en.wikipedia.org/wiki/Wi-Fi_Protected_Access#Security_in_pre-shared_key_mode' title='Wi-Fi Protected Access on Wikipedia'&gt;uses the SSID as the salt&lt;/a&gt;. Which is to say, it literally &lt;em&gt;broadcasts the salt to everyone in range&lt;/em&gt;. &lt;strong&gt;Salts are not secrets.&lt;/strong&gt;&lt;sup id='fnref:2'&gt;&lt;a href='#fn:2' rel='footnote'&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;So, anyway, back to Marc’s answer. I’m going to give it &lt;strong&gt;5 points&lt;/strong&gt; as a nice reasonable starting point, but then add a &lt;strong&gt;“stupid Wikipedia advice”&lt;/strong&gt; bonus multiplier, bringing the total for this answer up to, say, &lt;strong&gt;10 points&lt;/strong&gt;. A strong start for our first contestant! Let’s see what happens next!&lt;/p&gt;

&lt;h4 id='two_salts'&gt;“Two salts”&lt;/h4&gt;

&lt;p&gt;Yep. The &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; code distinguishes between a “master salt”, configured in a central .properties file, and the per-password salt passed to the &lt;code&gt;hash()&lt;/code&gt; function. But this is just silly: &lt;strong&gt;having an extra salt adds nothing but fragility to the system&lt;/strong&gt;. Bad idea for &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; — but another solid observation from Marc! &lt;strong&gt;6 points&lt;/strong&gt;!&lt;/p&gt;

&lt;h4 id='write_your_own_hashing_code'&gt;“Write your own hashing code”&lt;/h4&gt;

&lt;p&gt;Ouch! This is the final nail in the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; &lt;code&gt;hash()&lt;/code&gt; coffin, and it’s a doozy. The fun part is that the &lt;a href='http://owasp-esapi-java.googlecode.com/svn/trunk_doc/1.4/org/owasp/esapi/Encryptor.html#hash(java.lang.String,%20java.lang.String)' title='org.owasp.esapi.Encryptor.hash Javadocs'&gt;javadoc for the method&lt;/a&gt; even refers us to the &lt;a href='http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html' title='Matasano Chargen: Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes'&gt;good Mr. Ptacek’s article on secure password storage&lt;/a&gt; — an article which happens to contain the none-too-subtle exhortation&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No, really. Use someone else’s password system. Don’t build your own.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;…and what did the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; guys do? &lt;strong&gt;They built their own.&lt;/strong&gt; Let’s take a look at it now:&lt;/p&gt;
&lt;script src='http://gist.github.com/276928.js?file=JavaEncryptor.java' type='text/javascript'&gt;&amp;nbsp;&lt;/script&gt;
&lt;p&gt;Yep, that’s kind of exactly what you don’t want to do. All custom and hand-crafted and such. &lt;strong&gt;What’s wrong with &lt;a href='http://en.wikipedia.org/wiki/PBKDF2' title='Password-Based Key Derivation Function 2 at Wikipedia'&gt;PBKDF2&lt;/a&gt; or &lt;a href='http://www.usenix.org/events/usenix99/provos.html' title='Provos and Mazières: A Future-Adaptable Password Scheme'&gt;bcrypt&lt;/a&gt;?&lt;/strong&gt; The differences are notable as well: for example, this &lt;a href='http://www.schneier.com/paper-low-entropy.pdf' title='Schneier, Wagner, et al: Secure Applications of Low-Entropy Keys (pdf'&gt;key-stretching&lt;/a&gt; code here doesn’t have an ‘iteration’ or ‘cost’ parameter to tune as computers get faster. Even if we stipulate that 1024 is a reasonable number of iterations on today’s hardware,&lt;sup id='fnref:3'&gt;&lt;a href='#fn:3' rel='footnote'&gt;3&lt;/a&gt;&lt;/sup&gt; it wont be 5 or 10 years from now. But given this code, there’s no way to change that constant at a later date — nor is there any way to tell what iteration constant was used for a given password hash. If you use this, you’re gonna be stuck with this.&lt;/p&gt;

&lt;p&gt;It also seems odd that the various extra rounds of hashing don’t make any use of the password: I’d sort of expect that you’d want to make the computation depend on the password a bit more. Does that matter? &lt;strong&gt;No idea. I’m not a cryptographer.&lt;/strong&gt; Which is why I don’t go around designing my own password hashing functions. This is precisely &lt;a href='http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html' title='Matasano Chargen: Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes'&gt;Ptacek’s point&lt;/a&gt;: the details of these things are &lt;em&gt;hard to get right&lt;/em&gt;, and there are already &lt;em&gt;plenty of good options&lt;/em&gt;. So why build your own?&lt;/p&gt;

&lt;p&gt;This answer gets a solid &lt;strong&gt;10 points&lt;/strong&gt;, plus a &lt;strong&gt;5 point “death-blow”&lt;/strong&gt; bonus, for a total of &lt;strong&gt;15 points&lt;/strong&gt;. Marc takes an early lead! Can he hold on to it? Let’s find out!&lt;/p&gt;

&lt;h4 id='hide_configuration_file_naming_the_algo'&gt;“Hide configuration file naming the algo”&lt;/h4&gt;

&lt;p&gt;Security Ninja quotes Jeff Williams as saying,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The SecurityConfiguration interface stores all configuration information that directs the behavior of the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; implementation. Protection of this configuration information is critical to the secure operation of the application using the ESAPI. You should use operating system access controls to limit access to wherever the configuration information is stored.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At first glance, this might seem to be another violation of &lt;a href='http://www.petitcolas.net/fabien/kerckhoffs/' title='Partial Translation of La Cryptographie Militaire'&gt;Kerckhoffs’ principle&lt;/a&gt;, aka &lt;strong&gt;an example of “security through obscurity.”&lt;/strong&gt; To the extent that “security configuration” means stuff like algorithm names and the like, it should be perfectly okay to broadcast that to the world: the security of the system should not rely on these parameters being secret.&lt;/p&gt;

&lt;p&gt;However, I’m inclined to take &lt;strong&gt;a somewhat more charitable view&lt;/strong&gt;: I suspect that Jeff meant that the configuration needs to be protected because that’s where you configure the &lt;code&gt;MasterPassword&lt;/code&gt; and possibly other secrets. And these &lt;em&gt;do&lt;/em&gt; need to be kept secret.&lt;/p&gt;

&lt;p&gt;Of course, there’s the obvious point that &lt;strong&gt;configuring both secret things and not-very-secret things in the same place encourages fragility&lt;/strong&gt;. You might want to track the generic &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; settings in source control, for example — but the password is in there, and so checking the file in wouldn’t be so great. I think this is a valid point, but it’s not terribly strong. &lt;strong&gt;2 points.&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id='overuse_of_ninja'&gt;“Overuse of ‘ninja’”&lt;/h4&gt;

&lt;p&gt;This would be a good point, but for Marc’s &lt;a href='http://blog.wesabe.com/2007/05/14/super-ninja-privacy-techniques-in-insecure-magazine/' title='Super Ninja Privacy Techniques'&gt;own checkered past with the word&lt;/a&gt;. &lt;strong&gt;0 points.&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id='at_the_close_of_our_first_round_marc_has_an_impressive_33_points'&gt;At the close of our first round, Marc has an impressive &lt;strong&gt;33 points&lt;/strong&gt;!&lt;/h4&gt;

&lt;p&gt;Exciting! Thrilling! Etc! Stay tuned!&lt;/p&gt;

&lt;h3 id='a_challenger_appears'&gt;A Challenger Appears!&lt;/h3&gt;

&lt;p&gt;Our second contestant tonight is &lt;a href='http://codahale.com/' title='codahale.com'&gt;Coda&lt;/a&gt;, who hails from Berkeley, CA. Howdy, Coda! What can you tell us?&lt;/p&gt;

&lt;p&gt;&lt;a href='http://twitter.com/coda/status/7528299818'&gt;&lt;img src='/files/2010/01/12/coda.png' alt='@emerose DES, MD5, no integrity checks, no description of where the secrets are stored.' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Solid answers here, folks. And notice the style: Coda is dropping acronyms and sentence fragments like nobody’s business: he’s not asking questions, he’s telling it like it is. That full-stop at the end is particularly final, showing real conviction. What confidence! What showmanship! What an exciting contest!&lt;/p&gt;

&lt;h4 id='des_md5'&gt;DES, MD5&lt;/h4&gt;

&lt;p&gt;A powerful first answer from Coda, as he points out that &lt;strong&gt;no one should be using these algorithms anymore&lt;/strong&gt;. Seriously. DES can be &lt;a href='http://www.copacobana.org/' title='COPACOBANA: A Codebreaker for DES and other Ciphers'&gt;brute-forced in a week&lt;/a&gt;, and MD5 collisions &lt;a href='http://merlot.usc.edu/csac-f06/papers/Wang05a.pdf' title='Wang and Yu: How to Break MD5 and Other Hash Functions'&gt;can be found in 15 minutes&lt;/a&gt;. These algorithms haven’t been good choices since the early 90s. &lt;strong&gt;6 points&lt;/strong&gt; each for these important observations; add in the &lt;strong&gt;one-two comma splice combo multiplier&lt;/strong&gt; to get &lt;strong&gt;18 points&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id='no_integrity_checks'&gt;No integrity checks&lt;/h4&gt;

&lt;p&gt;For his next move, Coda tacks hard into crypto-nerd territory, pointing out that the &lt;code&gt;decrypt()&lt;/code&gt; method doesn’t do any message authentication. Which is to say, &lt;strong&gt;it doesn’t provide any native protection against &lt;a href='http://en.wikipedia.org/wiki/Chosen_ciphertext_attack' title='Wikipedia: Chosen-ciphertext attack'&gt;chosen ciphertext attacks&lt;/a&gt;&lt;/strong&gt;. If a bad guy can control what gets passed to &lt;code&gt;decrypt()&lt;/code&gt; and see what comes out the other side, there are a whole bunch of fun attacks available to her.&lt;/p&gt;

&lt;p&gt;What does a chosen-plaintext attack look like, you ask? That’s a great question, because it allows me to refer you once again to the inimitable Mr. Ptacek, whose &lt;a href='http://chargen.matasano.com/chargen/2009/7/22/if-youre-typing-the-letters-a-e-s-into-your-code-youre-doing.html' title='Matasano Chargen: If you’re typing the letters A-E-S into your code, you’re doing it wrong'&gt;prime-time AES melodrama&lt;/a&gt; features a nice explanation of a chosen-plaintext attack against PKCS#7. To prevent this, &lt;strong&gt;the encryption code should wrap the ciphertext (or plaintext) in a &lt;a href='http://en.wikipedia.org/wiki/Message_authentication_code' title='Wikipedia: Message authentication code'&gt;MAC&lt;/a&gt; would prevent this attack — or else use the block cipher in &lt;a href='http://en.wikipedia.org/wiki/EAX_mode' title='Wikipedia: EAX mode'&gt;EAX mode&lt;/a&gt;&lt;/strong&gt; — and the decryption code should check it. Alas, &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; does neither of these things.&lt;/p&gt;

&lt;p&gt;This is a solid observation from our challenger: &lt;strong&gt;10 points&lt;/strong&gt;, plus a &lt;strong&gt;crypto-nerd bonus&lt;/strong&gt; to total &lt;strong&gt;18 points&lt;/strong&gt;!&lt;/p&gt;

&lt;h4 id='no_desription_of_where_the_secrets_are_stored'&gt;No desription of where the secrets are stored&lt;/h4&gt;

&lt;p&gt;I take it that Coda is here referring to the “master secret” used in encryption/decryption. The blog post doesn’t make this especially clear, but this secret is stored in the system-wide &lt;code&gt;ESAPI.properties&lt;/code&gt; file, and the “Security Configuration” section at the bottom of the page does provide a bit of guidance on how to protect that file. (To wit: ‘you should protect that file,’ more or less.)&lt;/p&gt;

&lt;p&gt;So &lt;strong&gt;there is, in fact, a little bit of a description about where the secrets are stored&lt;/strong&gt; — and given the problem, the system-wide .properties file with restrictive permissions is about as good an answer as you’re going to get. I would probably score this observation as &lt;strong&gt;0 points&lt;/strong&gt;, but for the fact that &lt;strong&gt;&lt;a href='http://github.com/wesabe/grendel' title='Grendel on Github'&gt;Coda can teach us all a thing or two about secret storage&lt;/a&gt;&lt;/strong&gt;. Instead, we’ll give him the benefit of the doubt, plus &lt;strong&gt;2 points&lt;/strong&gt;.&lt;/p&gt;

&lt;h4 id='coda_pulls_into_the_lead_with_38_points'&gt;Coda pulls into the lead with &lt;strong&gt;38 points&lt;/strong&gt;!&lt;/h4&gt;

&lt;p&gt;Impressive! Astonishing! Exciting! Stay tuned!&lt;/p&gt;

&lt;h3 id='dnouement'&gt;Dénouement&lt;/h3&gt;

&lt;p&gt;So. We’ve seen an impressive array of problems and observations about the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; storage API. Pulling them all together, it’s time for a bit of meta-critique. What have we learned?&lt;/p&gt;

&lt;h4 id='esapi_reinvents_too_many_crypto_wheels'&gt;&lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; reinvents too many (crypto) wheels&lt;/h4&gt;

&lt;p&gt;From password storage to encryption routines, &lt;strong&gt;the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; reference implementation uses custom crypto for just about everything&lt;/strong&gt;. The &lt;em&gt;algorithms&lt;/em&gt; used are, of course, implemented by the JCE provider — the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; folks aren’t crazy — but the authors &lt;em&gt;apply&lt;/em&gt; those algorithms in somewhat naive ways. And this leads to some drawbacks. So, for example, the &lt;code&gt;hash()&lt;/code&gt; function implements its own key-stretching code which is less flexible and future-proof than more mainstream alternatives; or again, the &lt;code&gt;encrypt()&lt;/code&gt; method doesn’t authenticate the cipher- or plaintext, opening a window to attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best strategy for dealing with these problems is to avoid them.&lt;/strong&gt; Outside the context of research, it’s hard to see why even highly capable cryptographers would bother building a new crypto building blocks.&lt;sup id='fnref:4'&gt;&lt;a href='#fn:4' rel='footnote'&gt;4&lt;/a&gt;&lt;/sup&gt; And there really are plenty of good options already available — PBKDF2 and OpenPGP’s PBE would be my choices for these particular problems. Because the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; code rolls its own routines, though, it’s very hard to evaluate whether or not it provides enough protection for a given threat model…&lt;/p&gt;

&lt;h4 id='esapi_has_too_many_fiddly_knobs_to_configure'&gt;&lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; has too many fiddly knobs to configure&lt;/h4&gt;

&lt;p&gt;In digging through the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; code, I found quite a few different settings and secrets that get configured in &lt;code&gt;ESAPI.properties&lt;/code&gt; — things like the master salt/secret and preferred encryption algorithm, but also internal regexes and PRNG algorithms. I don’t think that these things should be options at all: &lt;strong&gt;a security API should just “do the right thing” and be done with it&lt;/strong&gt;, all the time. Making these things configurable is, at best, really confusing — and at worst, it’s really dangerous.&lt;/p&gt;

&lt;p&gt;For example, I spotted this in the current SVN trunk version of &lt;code&gt;ESAPI.properties&lt;/code&gt;:&lt;/p&gt;
&lt;script src='http://gist.github.com/278470.js?file=ESAPI.properties' type='text/javascript'&gt;&amp;nbsp;&lt;/script&gt;
&lt;p&gt;Essentially, that boils down to: &lt;strong&gt;“Here is a knob. Its meaning and purpose are obscure. If you ever change it, you will be screwed.”&lt;/strong&gt; Things like this are serious misfeatures of the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt;.&lt;/p&gt;

&lt;h4 id='esapi_is_way_too_complicated'&gt;&lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; is way too complicated&lt;/h4&gt;

&lt;p&gt;Similarly, the code required to set up, configure, and use &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; is way too complicated. The detail of Security Ninja’s post is evidence enough of this: ideally, using and understanding the API wouldn’t require reading such lengthy blog posts. I realize that the words “enterprise” and “Java” bring with them an expectation of configurability and flexibility, but I think this is a Bad Thing. Not only is it unlikely that the developers using ESAPI will be able to make informed decisions about fixed IVs and authenticated encryption options — it’s &lt;em&gt;also&lt;/em&gt; unlikely that even the software security group or external auditors will be able to make the right call about this stuff.&lt;/p&gt;

&lt;p&gt;Ideally, I think, &lt;strong&gt;a security API should expose very few, simple interfaces which provide a “batteries included” approach to security&lt;/strong&gt;. So, for example, there should not be a &lt;code&gt;hash()&lt;/code&gt; function which requires you to pass in a salt along with the plaintext — instead, there should be a &lt;code&gt;hashCreate()&lt;/code&gt; (or whatever) method which generates a random, strong salt &lt;em&gt;for&lt;/em&gt; you and embed it in the hash value along with any other parameters necessary (cost factors or algorithm identifiers, say). A separate &lt;code&gt;hashCompare()&lt;/code&gt; method would then be responsible for checking a given plaintext value against the hash value, hiding all the details from the programmer. That’s a narrow point; the general one is: &lt;strong&gt;don’t make developers think&lt;/strong&gt; about this stuff; instead, do the right thing for them, and &lt;strong&gt;make it hard to screw up&lt;/strong&gt;.&lt;/p&gt;

&lt;h4 id='esapi_is_improving'&gt;&lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; is improving&lt;/h4&gt;

&lt;p&gt;Digging through the code also shows that the &lt;abbr title='The OWASP Enterprise Security API'&gt;ESAPI&lt;/abbr&gt; code in SVN has improved rather significantly from the v1.4 code we looked at in Security Ninja’s post. For example, the properties setting immediately following the above seems to control setting a ciphertext MAC,&lt;sup id='fnref:5'&gt;&lt;a href='#fn:5' rel='footnote'&gt;5&lt;/a&gt;&lt;/sup&gt; &lt;strong&gt;thus (presumably) remedying Coda’s second point above&lt;/strong&gt;. It also sounds like the &lt;strong&gt;default encryption algorithm has been changed&lt;/strong&gt; to the more modern AES-128, another sensible move. I haven’t looked through the v2.0 code extensively, but it’s good to see some of the problems identified have been fixed already.&lt;/p&gt;

&lt;h3 id='conclusion'&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;So, at the end of all this, what are we left with? We’re left with the fact that &lt;strong&gt;Coda wins the prize&lt;/strong&gt;! A round of beer, redeemable at next week’s BaySec, say? And the honorable second-place runner up mention award goes to Marc. Yay everyone!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I’ll post next week’s question &lt;a href='http://twitter.com/emerose' title='My Twitter page (emerose'&gt;on Twitter&lt;/a&gt; on Monday.&lt;/strong&gt;&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;“Security Question of the Week” is a tradition left over from my days at &lt;a href='https://www.wesabe.com/' title='Wesabe Home Page'&gt;Wesabe&lt;/a&gt; If you’re into this sort of thing, you might want to check out &lt;a href='http://spotthevuln.com/' title='Spot the Vuln'&gt;Spot the Vuln&lt;/a&gt; too…&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:2'&gt;
&lt;p&gt;“But wait,” you say, “I heard about some guys who &lt;a href='http://www.renderlab.net/projects/WPA-tables/' title='Church of Wifi WPA-PSK Rainbow Tables'&gt;released rainbow tables for WPA&lt;/a&gt; a few years back. Doesn’t that you’re wrong and we should keep salts secret?” Well, no. Those tables are effective simply because WiFi SSIDs aren’t, in practice, particularly unique. &lt;em&gt;Lots&lt;/em&gt; of folks, for example, are using an SSID of “default” or “linksys”. The Church of Wifi guys just bit the bullet and computed rainbow tables for the &lt;a href='http://www.wigle.net/gps/gps/Stat' title='SSID Stats on WiGLE.net'&gt;thousand or so most common SSIDs&lt;/a&gt; × the most common passwords. They’re counting on the fact that a lot of the folks with crappy passwords also never changed the default SSID… As long as you change your SSID to something more interesting and uncommon — to something reasonably unique — you have nothing to worry about from this kind of attack. &lt;a href='http://www.wpacracker.com/index.html' title='WPACracker.com'&gt;This kind of attack&lt;/a&gt;, on the other hand, is probably a bit more worrisome: better make sure you use a strong password as well.&lt;/p&gt;
&lt;a href='#fnref:2' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:3'&gt;
&lt;p&gt;A notion that, presumably, depends on the hash function being used…&lt;/p&gt;
&lt;a href='#fnref:3' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:4'&gt;
&lt;p&gt;So, for example, Colin Percival has gone and built &lt;a href='http://www.tarsnap.com/scrypt.html' title='The scrypt key derivation function and encryption utility'&gt;a new password-based key derivation function&lt;/a&gt;. And as far as I can tell, Colin is a really very smart and talented cryptographer. I bet &lt;a href='http://www.tarsnap.com/scrypt.html' title='The scrypt key derivation function and encryption utility'&gt;scrypt&lt;/a&gt; is great. But I wouldn’t recommend actually &lt;em&gt;using&lt;/em&gt; it for anything — at least not without a really good reason why more standard options won’t work…&lt;/p&gt;
&lt;a href='#fnref:4' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:5'&gt;
&lt;p&gt;While also allowing you to shoot yourself in the foot by turning it off…&lt;/p&gt;
&lt;a href='#fnref:5' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
   <author>
     <name>Sam Quigley</name>
     <email>quigley@emerose.com</email>
     <uri>http://www.emerose.com/~quigley/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Open for Business!</title>
   <link href="http://www.emerose.com//open-for-business.html" rel="alternate" type="text/html"/>
   <updated>2010-01-04T00:00:00-08:00</updated>
   <id>http://www.emerose.com//open-for-business</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m happy to announce that, as of today, &lt;a href='http://www.emerose.com' title='Emerose Advisory Services Home Page'&gt;Emerose Advisory Services&lt;/a&gt; is officially open for business! I also want to thank everyone for their kind words of support on &lt;a href='http://www.linkedin.com/companies/emerose-advisory-services' title='Emerose Advisory on LinkedIn'&gt;LinkedIn&lt;/a&gt;, &lt;a href='http://twitter.com/emerose' title='My Twitter page (emerose'&gt;Twitter&lt;/a&gt;, and elsewhere — it’s gratifying to hear from so many people who are as excited as I am.&lt;/p&gt;

&lt;p&gt;I started &lt;a href='http://www.emerose.com' title='Emerose Advisory Services Home Page'&gt;Emerose Advisory&lt;/a&gt; to fill three core security consulting needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security for Startups&lt;/strong&gt; A number of the startups launching right now are focused on doing some pretty interesting things with some pretty sensitive data, including personal information, location data, credit card records, bank passwords, even health records… My aim is to help these companies think through the security issues they face, and come up with security strategies that help rather than hinder fast iteration, innovation, and growth.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Startup Security for the Enterprise&lt;/strong&gt; Another common trend these days is enterprises adopting the tools and techniques of the startup world. Companies are evaluating cloud computing, infrastructure automation, and software as a service strategies in order to gain an edge on their competitors — but with these technologies come new and unfamiliar risks. My goal is to help companies evaluate their options, technologies, and vendors in order to make the best use of resources while still meeting policy and compliance requirements.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security for Companies In Between&lt;/strong&gt; Finally, there is a third category of company — established startups whose success means that they now face a new set of compliance challenges and customer expectations. Whether it’s a matter of completing a SAS-70 or SOX audit successfully, or building a solid application security program, Emerose Advisory can help make these initiatives a reality.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Does any of that sound like it’d be useful to you? Is there something not on that list that you need help with? &lt;a href='http://www.emerose.com/contact' title='Contact Page'&gt;Get in touch!&lt;/a&gt;&lt;/p&gt;</content>
   <author>
     <name>Sam Quigley</name>
     <email>quigley@emerose.com</email>
     <uri>http://www.emerose.com/~quigley/</uri>
   </author>
 </entry>
 
</feed>