3

For example, would this (pseudo)-code work?

let t = timeRightNow()
let message = stuffWhoseTimingCantBeLeaked()
waitUntilTime(t+1 second)
send message

Or similar? That way the time that the message is sent doesn't depend on the timing of stuffWhoseTimingCantBeLeaked().

Would an attacker still be able to determine how long stuffWhoseTimingCantBeLeaked() took to run?

PyRulez
  • 2,937
  • 4
  • 15
  • 29
  • 1
    Can I as the attacker launch something like a DOS attack. My goal is to slow down your system so that `stuffWhoseTimingCantBeLeaked` will take more than one second. Perhaps you could add a condition that if the process takes more than one second it errors rather than sending a message. – emory Feb 14 '16 at 00:57
  • @emory I was thinking that would be a problem. Probably would be an error message. – PyRulez Feb 14 '16 at 01:04
  • I think even with the error message, there is a timing issue. As an attacker, I will launch a DOS style attack until 50% of computations error. Then small changes in timing may mean the difference between result (time <= 1 second) and error (time > 1 second). I will collect large amounts of data and calculate averages. – emory Feb 14 '16 at 01:10
  • @emory Maybe after the first failure, the whole service goes down (can't get much info from a single failure). Or you just hope that attackers can't DOS. Or both. – PyRulez Feb 14 '16 at 01:11

1 Answers1

1

As long as t + s is sufficient to cover any delays in responses introduced by a DDoS style attack, where s is the number of seconds.

That is, hitting a service listener that calls the above in order to encourage stuffWhoseTimingCantBeLeaked() to take longer than s could reveal to the attacker how long, on average, stuffWhoseTimingCantBeLeaked() takes to execute, once the t + s barrier is broken.

To mitigate this, you could mask this extra time by detecting when your function takes longer:

let t = timeRightNow()
let s = 1
let waitTime = t + s
let message = stuffWhoseTimingCantBeLeaked()
let executeTime = timeRightNow() - t

if timeRightNow() > waitTime
  waitUntilTime(timeRightNow() + executeTime * csprng(2,1)) # Random wait of between 1 and 2 times the original execution time (integer)
else
  waitUntilTime(waitTime)
send message

Note though, with enough requests it might be possible to get an average that will even out, leaking the time taken to execute stuffWhoseTimingCantBeLeaked().

With higher values of s, the risk can be lowered further, at the expense of performance. You could also introduce detection of whether your web service is requested repeatedly from a certain user or IP address and then rate limit the connection.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178