Hacker News new | ask | show | jobs
by jcoglan 5117 days ago
The timing attack is if you check the tag, that fails, and then you don't do any further request processing. This shortens the request time. It depends quite a lot on what you're actually doing with the message, but in general you want to leak as little info as possible about what's happening during any crypto-related process.
3 comments

If your authentication and processing steps are distinct and independent, then you're not doing any good by not returning early (immediately after your authentication process). The only thing that the attacker can learn from the timing of the response is whether authentication was successful or not, what any useful API should convey anyhow.

The only good thing that "authenticating last" does is that it prevents the attacker from issuing lots of requests sequentially, thus brute-forcing your authentication, but this should be solved in another way, without slowing down legitimate users and overloading your servers.

But it only tells them that it failed, not that they got closer, like with the string-comparison based one. What does that gain an attacker if you already provide other feedback about the request being invalid? And not doing so would result in a bad user experience if you have users run into a bug somewhere and it fails silently so they don't know that nothing was actually done.
In some cases, not letting them know they've failed is nice. But the most common case to look out for is, if your auth/crypto process involves multiple steps, don't return early from it, or do anything that alters its runtime significantly. This leaks useful information in many situations. The course at http://crypto-class.org is better than me at explaining this stuff, and starts on Monday.
The leak that you're ostensibly timing is that in order to figure out how much of the candidate MAC string was valid, the target had to compare more byte, which takes more time, which adds observable lag to the error response.
Is the observable lag for a string comparison significant enough to be useful?

We're talking about such small amounts of time compared to the overhead of the full web stack.

The observable lag isn't usually significant enough if you only do it once but over many requests the stochastic factors can be compensated for.
You can compare success versus failure.

Success: check authentication, process data, commit, return 2xx status.

Failure: check authentication, return 4xx status.

The reason that you don't get any information from the difference in timing between the two branches is because you already get that information from the status code.

Now on the other hand, if you use naive string comparison, different failure branches will take different amounts of time. That is a security hole, and it's not what we're talking about here.