Comments:"Be careful with your random tokens — Meldium"
URL:http://blog.meldium.com/home/2013/2/19/be-careful-with-your-random-tokens
The UUID gem docs tell us exactly what's going on here:
A UUID is 128 bit long, and consists of a 60-bit time value, a 16-bit sequence number and a 48-bit node identifier. The time value is taken from the system clock, and is monotonically incrementing. However, since it is possible to set the system clock backward, a sequence number is added. The sequence number is incremented each time the UUID generator is started. The combination guarantees that identifiers created on the same machine are unique with a high degree of probability.And RFC 4122, which defines the UUID standard, goes one step further. (Update: thanks to Douglas Murth for pointing out in the comments that this is a "version 1" UUID. A "version 4" UUID uses 126 psuedorandom bits).
Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example. A predictable random number source will exacerbate the situation.It's important to note that this problem is not a bug or vulnerability in resque-status - the library makes no claim to return random job IDs. The bug here is in the application misusing the IDs by treating them as authorization tokens.
Fixing the glitch
So how did we fix the bug? One option would be to upgrade to a newer version (0.4.0 or later) of resque-status, which now uses SecureRandom.hex
to generate job_id
s. This isn't really a reliable fix: resque-status makes no promises about the IDs it returns, and the implementation may change again in the future.
Because we're paranoid about these things, we're generating our own random tokens (using SecureRandom.hex) and passing them into each job. That way we know where the tokens are coming from, independent of changes in our library code, and we don't need an extra authentication check on job ownership. Here's a snippet of our base Job
class that shows how we return results from a Resque job: