Skip to content

Instantly share code, notes, and snippets.

@arirusso
Created April 30, 2012 01:51
Show Gist options
  • Save arirusso/2554841 to your computer and use it in GitHub Desktop.
Save arirusso/2554841 to your computer and use it in GitHub Desktop.
Ruby methods for protecting against timing attacks
#!/usr/bin/env ruby
#
# Ruby methods for protecting against timing attacks
#
module ExpressionTimer
# a shortcut to ExpressionTimer.send that passes in the object for which this module
# was included
#
# @param [Numeric] seconds the minimum number of seconds to wait before returning
# @param [Array] send_args a splat of args to pass into self.send
# @return [Object] the result of calling send on this object
def timed_send(seconds, *send_args, &block)
ExpressionTimer.send(seconds, self, *send_args, &block)
end
# a wrapper for Object#send that protects against timing attacks by
# ensuring that it does not return from evaluation before a specified
# minimum time
#
# @param [Numeric] seconds the minimum number of seconds to wait before returning
# @param [Object] object the object to call send on
# @param [Array] send_args a splat of args to pass into Object#send
# @return [Object] the result of calling send on object
def self.send(seconds, object, *send_args, &b)
block(seconds) { object.send(*send_args, &b) }
end
# wrap a block with a method that protects against timing attacks by
# ensuring that it does not return from evaluation before a specified
# minimum time
#
# @param [Numeric] seconds the minimum number of seconds to wait before returning
# @param [Array] block_args splatted arguments to pass in to the block
# @yield [Array] the wrapped block to evaluate with block_args passed in splatted
# @return [Object] the result of yielding to the block
def self.block(seconds, *block_args, &block)
start = Time.now.to_f
result = yield(*block_args)
finish = Time.now.to_f
sleep (seconds - (finish - start))
result
end
end
#
#
# examples:
#
#
# send:
puts ExpressionTimer.send(0.25, "password attempt!", :==, "my password!")
# or a block
puts ExpressionTimer.block(0.75) { "password attempt!" == "my password!" }
# or with arguments passed into a block
puts ExpressionTimer.block(1.25, "password attempt!", "my password!") { |s1, s2| s1 == s2 }
# or with an included module (don't actually include it in String, this is just a demo)
class String
include ExpressionTimer
end
password_attempt, real_password = "password attempt!", "my password!"
p password_attempt.timed_send(0.75, :==, real_password)
@RobertLowe
Copy link

Why not use timeout.rb?

Also http://www.ruby-doc.org/core-1.9.3/Thread.html#method-i-abort_on_exception

Finally, include the gist text on your blog, I barely noticed the linkage.

Cheers

@arirusso
Copy link
Author

Isn't timeout.rb a time limiter? How do you see that working here?

I normally use Thread#abort_on_exception but I don't see much opportunity for an exception in this thread, unless someone passes in a negative value for seconds ? lemme think about that one

@RobertLowe
Copy link

Sorry, I read the gist in a rush, timeout.rb is a limiter

Still why the thread?

@arirusso
Copy link
Author

Yeah, it may not be necessary -- most of the timers I've written before were actually multithreaded so I wrote that out of habit.

I'll give it a shot in the main thread and change it if it seems reliable.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment