0

I am building a web app that allows login with an email and password. I understand that I need to use a timing safe function to compare the passwords to prevent timing attacks. However I realized that the emails might be vulnerable to the same attack. I am unsure how to prevent timing attacks on the emails.

The emails are stored in a database and the database handles finding the user with the matching email:

 SELECT * FROM users WHERE email = $1

This means that the database handles searching through all the users' emails and looking for a match. The internal database function (in this case the db happened to be PostgresSQL) used to compare the emails provided in the WHERE clause with the ones in the database is not timing safe (I assume because that would be really slow and inefficient). This is an issue at login where inputted emails must be compared against the entire (or much of) the database.

How can I prevent timing attacks on email?

  • 1
    Assuming you have an index on the login id column (... you should...), retrieval should be a constant-time operation; profile, but there's likely no significant difference between there/not there. Note that the bulk of the time for user retrieval is going to be shipping the data to/from the database server itself. – Clockwork-Muse Jan 29 at 0:58
  • @Clockwork-Muse I think the id is irrelevant here. The email is being compared not the id. – JBis Jan 29 at 0:59
  • "login id" is being used as a standin for the email. You're trying to prevent user enumeration. – Clockwork-Muse Jan 29 at 1:01
  • @Clockwork-Muse I'm confused what you mean. – JBis Jan 29 at 1:02
  • @Clockwork-Muse Are you thinking of "constant time" as in O(1) time? If so, then know that the same term is applied to a different concept in some contexts. It means that execution time is independent of the specific value of any (potentially) sensitive input variables. It's an unfortunate name because constant seems to imply that the run time is always the same (or bounded below a constant) but actually only requires that measuring execution time doesn't leak information. – Future Security Jan 29 at 1:33
1

From the comments:

Store a second column with the hash of the email. When a user submits their email and password, hash the input email and look it up in the db. This will mitigate timing attacks to the point where it is insignificant.

How hashing mitigates timing attacks is discussed on the below post:

https://stackoverflow.com/a/27029501/7886229

| improve this answer | |
1

Interesting question.

Definitions

Just to make sure we're on the same page about definitions, I'm taking "timing attack" according to the wikipedia definition:

Every logical operation in a computer takes time to execute, and the time can differ based on the input; with precise measurements of the time for each operation, an attacker can work backwards to the input.

The way I think about this is that a naively-implemented strcmp will walk through the strings and quit as soon as it finds a char that's different. Something like (pseudocode)

bool strcmp(char[] stringA, char[] stringB) {
  for (i=0; i<len(stringA); i++) {
    if (stringA[i] != stringB[i])
      return false;
  }
  return true;
}

That means that strcmp("aaaaaa", "aaaaab") will take longer than strcmp("aaaaaa", "bbbbbb"). Basically the longer it takes, the "closer" you are to the secret string. Using a "timing attack oracle" (a server that knows the secret value and gives you timing info), an attacker can figure out the first letter, then the second letter, then eventually the whole string.


Timing safe functions for passwords

I feel required to ask why you need a timing safe password compare function? You're not storing passwords in plaintext are you?

If you're storing password hashes and doing a strcmp on two hash values, then timing safety is not a thing you need to think about. (Maybe I'm wrong and you can still do effective timing attack on hashes?)


Timing safe functions for usernames / email addresses

Now to your actual question. Let's start with the threat model. I suppose you're worried about user enumeration attacks.

With something like a password or a cryptographic key, there's one valid value and being able to guess it one character at a time, rather than the whole string at a time, really really speeds up the brute-force.

With usernames / email addresses, there are many valid values. I wonder how much a "closeness" meter actually helps? And close to what? In what order is postgres going to iterate through the keys? I honestly don't know, but my intuition is that it probably doesn't make nearly as big a difference as it does for a cryptographic key.

That said, if we're going to worry about timing attacks, I assume you have already mitigated every other aspect of user enumeration attacks?

  • When a user submits a username & password, you give absolutely no indication whether the username or the password was wrong. Rapid7 has a great article on this topic.
  • You use some sort of rate-limiting or IP banning to prevent repeated login attempts.

In fact, if you have an effective rate-limiting mechanism, then an attacker probably can't do the thousands of queries they need in order to do statistical timing analysis.

| improve this answer | |
  • Firstly, I am hashing password. Hashed passwords are susceptible to the same timing attacks as non hashed passwords. In fact, the node crypto timing safe compare function only works on things of the same length because you are supposed to only do them on hashes (which are the same size). – JBis Jan 29 at 1:47
  • Rate limiting doesn't solve anything. It just, at best slows attackers down, but with multiple IPs the rate limiting is in effective for or difficult to implement. – JBis Jan 29 at 1:47
  • 1
    @JBis Can you give a link for timing attacks on hashed passwords? Sounds like I'm about to learn something. – Mike Ounsworth Jan 29 at 1:48
  • 3
    Hashing (on the server, obviously) has been recommended as a standard mechanism to defeat timing attacks, actually. Because the attacker cannot control one byte at a time of the hash digest while keeping all preceding bytes the same (at least, not for the full digest length; this would require a preimage attack on the hash function), and furthermore the attacker doesn't know the per-user salt and therefore cannot compute the digest themselves at all, they cannot launch a linear-time attack on the password even if given perfect timing data. – CBHacking Jan 29 at 2:01
  • 2
    @MikeOunsworth If the attacker could use a timing attack to extract the password digests, this would be a very serious security issue. Not as serious as getting the unhashed passwords out, but still very bad; most user passwords aren't going to withstand a dictionary attack on the hash no matter how expensive it is (it can't be too expensive for the login server). However, a timing attack assumes the attacker can submit candidate strings for comparison (hashes), so you can edit one byte at a time. If the input is hashed on the server side, changing a single byte will completely change the hash – CBHacking Jan 29 at 2:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.