Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This doesn't address timing attacks, which are why this is done in the first place. If the code checks only for a username existing and returns the error message, this takes a measurably different amount of time compared to then also looking up if the password matches.

The error shown isn't to dissuade people from using web pages to try to gain access to accounts - it's because the raw code itself doesn't know which is which, and writing code that does enables fast-paced timing attacks.



> This doesn't address timing attacks, which are why this is done in the first place.

This is not done because of timing attacks, it's done because of cargo-cultism and laziness.

> The error shown isn't to dissuade people from using web pages to try to gain access to accounts - it's because the raw code itself doesn't know which is which

Modern systems store passwords salted and hashed with KDFs. The stored hash must be retrieved before the provided password can be checked as you need the stored hash's work factor and salt, which are stored alongside (/as part of) the hash. Such a system necessarily knows which is which.


> This doesn't address timing attacks, which are why this is done in the first place.

I don't follow. Surely the reason to hide usernames is not to prevent a timing attack that would reveal... usernames.


I might be missing what you're not following, but here's a quick explanation (and a reason why it's not a concern)

Correct username, correct password: takes 30ms to execute the code

Correct username, incorrect password: takes 15 ms to execute the code

Incorrect username: Takes 7 ms to execute the code.

You fuzz usernames, you get one that takes 15 ms, you know that's a valid username. You then start working the password.

Not necessary on most systems, because we're working at speeds that are measured in nanoseconds, and since we're using networks for many attacks, the delays are unpredictable and measured in (at least) milliseconds.


I understand how the timing attack works. I don't understand how it's a justification for hiding usernames. "You need to try to hide A because if you're not careful they can find A."

If anything the timing attacks weaken the argument against hiding usernames.


I don't see how what you say is really true in a system with properly hashed/salted passwords.

    SELECT "Id", "Hash", "Salt" FROM USERS WHERE "Email" = $input

    if (results.length == 0) return -1; //No record, bad user, return early...
    if (results["Hash"] != Hash(pwd.trim(), results["Salt"]) return -2; //invalid password


If you have an index on your "Email" field in the database, there may be discernible difference between the time taken to check the index and return '0 rows', vs getting a match and actually reading the appropriate data to build the result row.

I don't know if there's a solution to that in the general scheme of things, other than making the variance of query times between no user and some user as small as possible.


And, if you're returning the correct error message, it doesn't matter.. the whole point of a timing attack is to determine the difference.

IMHO usability is more important. There are other ways to improve security. Rate limiting with < N failed attempts via an IP in under < X minutes.


Your code has precisely the timing attack he tried to describe in it. You're returning early when a user doesn't exist.


So? I'm advocating showing the correct error message... a timing attack is irrelevant in this case.

For that matter, adding a random 500-2000ms timer before returning a failed result would likely be as effective, and not lead to a bad user experience.


> This doesn't address timing attacks, which are why this is done in the first place. If the code checks only for a username existing and returns the error message, this takes a measurably different amount of time compared to then also looking up if the password matches.

Timing attacks are solved by how you implement the backend checking code and not how you present the result to the end user in the most user friendly manner.


That would make it an even worse pattern, your implementation leaking into your UI.


I feel like the variance in network latency is going to be an orders of magnitude larger than the extra time it takes to test a password.


It is, but with a sufficiently large number of attempts you can account for jitter. A good summary (with links to existing research) can be found here:

http://blog.astrumfutura.com/2010/10/nanosecond-scale-remote...


Doesn't matter.

Network latency variance just means you need to sample more. It doesn't prevent the attack.


So what, you're going to take a large number of samples for each username attempt?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: