Sunday, 24 July 2011

Password Sodium

So on food labels they often show the amount of Sodium in the food, which is useful, but less useful than if they showed the actual amount of Salt, which is what you need to watch out for (apparently the conversion is Salt = Sodium x 2.5).  Putting Sodium instead of Salt is a trick by manufacturers to make high in Salt products look like there is less Salt in the food than there actually is.

So I have been thinking about better ways to authenticate via passwords recently, which has nothing to do with food labels, but everything to do with hiding useful information.  I have been thinking about ways to make an authentication scheme secure even if an attacker gets access to the password hash.  So far the problem as I see it is that an attacker is always able to use a dictionary of passwords to try and get a match with a password hash.  We can make this computationally expensive, but we can't stop it without removing some vital piece of information.  I still believe there is scope for a creative solution here, but it occurred to me we could also transform the problem into something we are better at solving.

If we encrypt the password salt then if the attacker gets hold of the password hashes they will be of no use whatsoever because because it is computationally infeasible to guess the salt. I am going to call the encrypted password salt ... the password sodium.

This suggestion, as I mentioned, merely transforms the problem for the attacker from one of gaining access to the password hashes, to gaining access to the password hashes and the salt encryption key.  A practical example of this would be to say that instead of a SQL Injection vulnerability being enough to get the password hashes and begin cracking them, the attacker needs to compromise the machine as well (depending on where the encryption key is stored).

The hope here is that we have made the task more difficult for the attacker.  That hope depends on how and where we store our encryption keys, but that certainly is not a new problem and many companies have standard solutions.

Certainly with the numerous high-profile password hash disclosures that have happened over the last couple of months adding a little defense in depth by encrypting password salts should help protect people's passwords and minimise the damage of password hash disclosures.

Tuesday, 19 July 2011

Zero Knowledge Password schemes

So in my previous post I was lamenting that as it stands today, for the majority of the Internet, when I authenticate to a website I have to send them my password.  It's obvious that if that wasn't a requirement then this would be better.

This caused me to read up more on Zero-Knowledge Password authentication schemes, and I came across the Secure Remote Password (SRP) Protocol (very nicely summarised here).  However, in the security analysis (given on the linked page) of SRP there was the following property:

"If the host's password file is captured and the intruder learns the value of v, it should still not allow the intruder to impersonate the user without an expensive dictionary search."

To me, this is not good enough.  Or at least if I am giving my list of all criteria I would like my authentication protocol to meet, one of them would be that "even if the password file is captured an attacker cannot recover the password".  This sounds like an impossible dream, but I hope it is not. 

Initially I imagined a change to SRP that I thought might do the job.  If we had 2 generators for the group, g1 and g2 (so in the current scheme replace references to g with g1), and 2 passwords, P1 and P2, then we could construct v as:

  1. x1 = H(s1, P1)
  2. x2 = H(s2, P2)
  3. v = g1^x1 . g2^x2
The rest of the protocol could be minimally altered to accommodate this.  Hopefully you can see that an attacker with access to v, s1 and s2, could in fact hit upon multiple P1 and P2 values that create the same v value.  So even if the attacker was able to create all possible P1 and P2 values, they would not be able to tell if they were the actual password values.

But the suggestion has a drawback.  Well it has a couple.  Firstly it requires the use of 2 independent passwords.  Secondly, if an attacker got the password files for 2 different sites using the same g1 and g2 (and using the same group) then they could solve for P1 and P2 (from a list of candidates after a brute-force attack).  Lastly, my analysis is optimistic in saying that multiple solutions exist because the range of possible passwords is so much smaller than the range of possible x values.

Still, it's fun to play with these ideas, and you never if you might hit on the right combination :)

Sunday, 17 July 2011

Passwords - the worst kept secret

So I'm writing some training material and I'm making a note that we don't use HTTP Authentication on the Internet anymore, it has loads of disadvantages.  Well it is supposed to anyway, I really couldn't find much detail on exactly what those disadvantages were?  I mean sure if there is a MITM then if you use Basic Auth then the MITM will get your password, or if you use Digest Auth then a MITM can downgrade to Basic Auth, or perhaps mount a dictionary-attack on your password.

Still, since the vast majority of web sites use forms-based authentication, what is the real difference (assuming you are using SSL/TLS)?  You are still sending your password over the inter-tubes.  Maybe I am missing something, I don't know.

To me though both Basic and Digest Auth had one advantage, the browser asked for my password and not the web page.  Why is that important?  Well there are a lot of spoofing attacks out there that try to fool users into entering their passwords into fake pages.

Entering passwords into fake pages is clearly a problem but really it isn't the fundamental problem.  The fundamental problem is that I am entering my password into a web page and that my password is being sent to the server at all.  Authentication is based on something you know, have or are, and so passwords fall into something you know, which means they should be a secret.  It's much easier to keep a secret if you never have to enter it into a web page and send it across the Internet and have it processed and stored (in some form) by someone else.

The 'what you know' requirement is merely proving that you know something, and while telling someone what you know does prove it, there are other ways to prove you know something without giving it away (see zero-knowledge password proof).

This does of course assume that a user and a site have agreed on a password already, and although I couldn't dig up much on schemes that don't have this requirement, I don't see why it shouldn't be possible.  A user could register a f(password) (a function of their password) and then authenticate at any time by providing g(password) where the site can convert f to g.  Note, I say possible, not easy, I haven't really given this much thought.

If the browser could be relied upon to do this securely on behalf of the user then it would eliminate many authentication concerns plaguing the Internet today, such as; spoofing authentication pages, MITM authentication attacks, server-side password or password hash disclosure, user password re-use.

Seems like it is definitely worth some more investigation ...

Monday, 4 July 2011

SQL Injection MMM

So I introduced the concept of a Mitigation Maturity Model (MMM) in a previous post, and I created a model for Cross-Site Scripting.  In this post I would like to do the same thing for SQL Injection.

SQL Injection is both an easy and difficult attack to create a maturity model for; on the one hand the mitigations for SQL Injection are well known, on the other hand to rank them is less straight-forward.  Nevertheless, let's have a go:
  1. None.  No protection.  Some protection from input validation but no effort to specifically protect against SQL Injection.
  2. Basic.  Strip SQL syntax characters.  Depending on the string delimiter being used for SQL, either single or double-quote characters are stripped.
  3. Intermediate.  Parameterised Queries (a.k.a. Prepared Statements).  All SQL commands are made using parameterized queries.  Any stored procedures are rigorously reviewed for potential SQL Injection flaws.
  4. Advanced.  Object-Relational Mappings (ORM).  All SQL commands are replaced with ORM calls.  Any stored procedures are rigorously reviewed for potential SQL Injection flaws.
So the model I have provided here contains no surprises, but I think I have to justify why I think ORM is a more mature mitigation than a parameterized query.  I actually think both are perfectly valid mitigations in their own right, and I struggled to decide if I should choose one as more mature than the other.  In the end what tipped ORM as a more mature mitigation was simply that parameterized queries still take a string (the SQL query with placeholders), and short of reviewing all these strings, there is no way to know if that string was dynamically constructed.  For this reason I believe you can have more confidence in ORM, since there is no way for a developer to abuse it (short of using direct queries in the ORM API, but these can easily be audited).  I doubt everyone will agree with my logic on this, but I think it's a reasonable argument.

So SQL Injection is probably one of the easier attacks to put in a MMM since the mitigations are so well understood.  The real test of how useful the idea of a MMM will be is determining if it can be applied to the majority of high-risk attacks applications must face.