I know this is a toy example, but really, people should not be storing passwords in plaintext in a database. jBCrypt has a simple API, and can be used from Clojure.
Also, the password authentication finishes early if it detects a mismatch between the given password and the one in the database. This makes it fairly easy for an attacker to get people's passwords with a straightforward timing attack. To fix it, always go through all the characters in the strings to compare them.
"Also, the password authentication finishes early if it detects a mismatch between the given password and the one in the database. This makes it fairly easy for an attacker to get people's passwords with a straightforward timing attack. To fix it, always go through all the characters in the strings to compare them."
The password check is a database query that, since there are no indices on the users table, will check for string equality in every row of the table. Timing the response tells you a lot about the number of users, and the instantaneous server load, not so much about how closely the latest guess matches someone's password.
Even with a more optimized program, I'd be surprised if "fairly easy" were an accurate characterization of the effort to separate timing of comparing one extra character of a password from all the other stuff going on during a request: database access, routing, parsing query parameters, load from other requests, garbage collection pauses, network latency... The signal-to-noise ratio is just too low.
> Even with a more optimized program, I'd be surprised if "fairly easy" were an accurate characterization of the effort to separate timing of comparing one extra character of a password from all the other stuff going on during a request: database access, routing, parsing query parameters, load from other requests, garbage collection pauses, network latency... The signal-to-noise ratio is just too low.
Timing attacks are possible over networks, even when the timing differences are minuscule. [1]
That's an interesting article. While I feel less certain of my original position, I am still skeptical about a timing attack based on the time required to compare two password strings for equality.
Note that while the article deals with similar sources of noise, it also deals with a larger signal. They are trying to time a decryption process, which has a high computational complexity by design. We are talking about timing the difference between checking for equality of the first few characters of a string, versus checking for equality between all characters of strings that are unlikely to be more than 20 characters long.
Chrome tells me that it took 109 milliseconds to load a 50-line stylesheet on my personal website.
So the operation we are trying to time shows a lot of variability even if you can isolate it by running that code directly in a terminal, and a typical small HTTP response takes up about a million times more runtime.
Yes, these are very crude estimates. Good profiling is much harder than this. Still, if I knew this was the only security hole in my application, I'd be feeling very safe.
http://www.mindrot.org/projects/jBCrypt/
Also, the password authentication finishes early if it detects a mismatch between the given password and the one in the database. This makes it fairly easy for an attacker to get people's passwords with a straightforward timing attack. To fix it, always go through all the characters in the strings to compare them.
Fantastic article otherwise, though.