Redis Quickie: Scramble and unscramble your commands in Node.js

Kyle
3 min readMay 3, 2017

--

This is part 30 of my Node / Redis series. The previous part was Ice wine, Redis and Microcontrollers.

Redis isn’t a multi-user database. Once you’ve AUTH’ed you’re in. You can do anything. Normally, that’s not a huge deal as Redis sits behind a script or app.

I’m working on a project where my Redis instance has the chance to be messed with. Not a big chance, but a chance nonetheless. In redis.conf you have a couple of options to prevent a particular command from being issued:

  • Disable the command completely — no client will be able to issue that particular command,
  • Rename the command to something obscure and a client without the knowledge cannot issue the command.

Both of these things can be accomplished with the rename-command config option in redis.conf. This will disable the command KEYS completely:

rename-command KEYS ""

Where as this will rename it:

rename-command KEYS donteverusethiscommand

In my situation, I want to just blanket rename everything into longish random characters. That way if someone manages to make a connection to my Redis instance, they’ll have a pretty hard time of doing anything useful.

node_redis has a cool configuration feature that allows you to pass an object that de-scrambles the commands to make a script behave normally. To accomplish this you have to pass in an object with the property names as the original commands and the values as the renamed versions. It looks a bit like this:

{
...
"rename_commands" : {
"KEYS" : "donteverusethiscommand"
}
}

In your script you’ll be able to use the commands as normal. The normal syntax is now translated transparently to the renamed commands.

client.keys('*', function(err, allthekeys) { ... });

Now, dear reader, you may remember that I am a lazy individual. Redis has more commands than you might imagine (175+ at current count) and I just didn’t want to manually configure each command. This is a job for a simple tool. It should do three things:

  • Generate a random sequence of characters for each command,
  • Generate the rename-command configuration snippet,
  • Generate the JSON object for node_redis that you can require into your client connection object.

The random sequence of characters are expressed as hexadecimal representations of bytes. In my example I’m using 8 bytes of random data that is represented in 16-digit hexadecimal. That might not sound like a lot, but it would take a decent about of time to brute force something like this even at 1,000,000 ops/sec:

From Open Security Research

In addition, I also prepended a ‘r’ to the start of each command. I ran into an odd issue where starting a renamed command with a number yielded very unexpected output. This is a cheap work around.

The tool can be invoked by running:

node index.js --json ~/path/to/outfile.json --conf ~/path/to/outfile.conf 

Optionally, you can add in a randomlength argument to vary the size of the random string.

Concatenate the contents of the “outfile.conf” to the end of your configuration file (redis.conf usually) and restart your server. Finally, before creating your client in the Node.js script, make sure your connection object includes the contents of the outfile.json at the rename_commands property . There is an example in the repo.

Finally, I would be negligent to oversell this ‘security.’ This type of security isn’t really like a password. All of these values are stored in your redis.conf file in clear text. If someone was to gain access to that file, all of these measures would be for naught. However, it will keep the casual prankster from running FLUSHDB on a production dataset. Also, if new commands are added by the Redis modules system, those will not be scrambled. Likewise, if new native commands are added, you’ll need to make sure they are in the redis-commands node.js module to be protected (or add them in manually).

You can pick the tool up over on github.

--

--

Kyle

Developer of things. Node.js + all the frontend jazz. Also, not from Stockholm, don’t do UX. Long story.