Aug 03 2013
TL;DR: if you use redis-namespace and you use send
, Kernel#exec
may get called. Please upgrade to 1.0.4, 1.1.1, 1.2.2, or 1.3.1 immediately.
Link to the fix: https://github.com/resque/redis-namespace/commit/6d839515e8a3fdc17b5fb391500fda3f919689d6
The Problem
Redis has an EXEC command. We handle commands through method_missing
. This works great, normally:
r = Redis::Namespace.new("foo") r.exec # => error, not in a transaction, whatever
Here’s the problem: Kernel#exec
. Since this is on every object, when you use #send
, it skips the normal visibility, and calls the private but defined Kernel#exec
rather than the method_missing
verison:
r = Redis::Namespace.new("foo") r.send(:exec, "ls") # => prints out your current directory
We fix this by not proxying exec
through method_missing
.
You are only vulnerable if you do the always-dangerous ‘send random input to an object through send
.’ And you probably don’t. A cursory search through GitHub didn’t find anything that looked vulnerable.
However, if you write code that wraps or proxies Redis in some way, you may do something like this.
The official Redis gem does not use method_missing
, so it should not have any issues: https://github.com/redis/redis-rb/blob/master/lib/redis.rb#L2133-L2147
I plan on removing the method_missing
implementation in a further patch, but since this is an immediate issue, I wanted to make minimal changes.
Testing this is hard, #exec
replaces the current running process. I have verified this fix by hand, but writing an automated test seems difficult.
:heart::cry: