Checked and the Mastercard one someone posted below doesn't seem to be vulnerable to this. My real card number and a dummy mastercard number with valid prefix and check digit both returned a 200 OK in around 1.01s. A random 16digit number without valid check digit returned 400 Bad Request in about 800ms. Decided to check that one since they have a completely useless machine-readable catchpa.
For Visa it was 835ms for valid, 762ms for dummy, prefix and check digit appears to be checked client side.
100ms is /massive/ for a timing delta but you really need a lot of samples. I have exploited timing deltas that were not much more than a handful of machine code instructions in terms of execution time. But you really do need a lot of samples to confirm small deltas. It starts getting impractical for many APIs (someone will notice, hopefully).
Easily accommodated for. I can get the execution run-time and store in an average in memory for some time-period and have the sleep function top-up the difference between the two paths. Not sure what the "proper security" method is to prevent execution deltas.
Why not just run the thing (which takes some small fraction of time), then pad to five seconds, and respond. Since your work will be done in milliseconds, padding to nearest five seconds will remove any noise.
And it's not a thing anyone has a legitimate interest in submitting more than that per second.
The parent said "pad to 5 seconds" not "add 5 seconds". Thus everything would be 5 seconds (never 5.01). The difference between a hit and a miss would be exactly 0s. Note that I'm not advocating for or against this solution; rather, clarifying the conversation.
Depends. With comparison functions you can implement a constant time comparison that takes the same amount of time. In this case it isn’t really a crypto problem, so anything where we are confident about things taking the same amount of time is fine. Basically in some parent method/func make sure we always spend 2000ms or whatever time is that is always greater than the max runtime of the slowest path. Secondary / defense in depth mitigations would be rate limiting this page and making it purposefully slow on response, just to make it that much harder to collect samples / abuse it without being noticed. The captcha is a nice touch, but it didn’t seem particularly strong (a good captcha solver could break it). Still, captcha will chase off a lot of script kiddies. You don’t have to be faster than the bear, just faster than the slowest person ;)
rand() produces linear distributon, which is uniform. Do I understand properly that rand() + rand() would return normal distribution, so #2, for which you can determine the non uniformity?
What would be a proper first step to harden API for timing attacks?
For Visa it was 835ms for valid, 762ms for dummy, prefix and check digit appears to be checked client side.