Redis exposed to the internet
An unauthenticated Redis reachable from an untrusted network is not a data exposure with a code-execution edge case. It is remote code execution, using documented commands, working as designed.
This is worth being precise about, because “it’s only a cache, there’s nothing sensitive in it” is the reasoning that leaves these instances open — and it misunderstands the risk entirely. The data is not the target. The server is.
The chain
Section titled “The chain”Redis lets a client change where it saves its data, and then save. That’s all that is needed.
CONFIG SET dir /root/.ssh— move the working directory.CONFIG SET dbfilename authorized_keys— name the dump file.SET x "ssh-rsa AAAA... attacker@host"— put a key in the keyspace.SAVE— Redis writes the dataset to that path.
The RDB file now sits at /root/.ssh/authorized_keys. It has binary preamble and
trailer around the value, but SSH ignores lines it cannot parse and reads the one
it can. The attacker logs in.
Nothing here is a bug. Every command is behaving as documented. Redis’s own
documentation acknowledges this directly, noting that CONFIG allows a client to
change the working directory and dump filename, and that this “may lead to the
ability to compromise the system and/or run untrusted code as the same user as
Redis is running.”
Three details decide how bad it gets:
- Which user Redis runs as decides whether the
write reaches
/root/.sshor is stuck in/var/lib/redis. /root/.sshis one target of many —/etc/cron.d/, a systemd unit, or a web root all work the same way.MODULE LOADis the shorter path where it’s available: load a shared object, execute code, skip the file-write dance entirely.REPLICAOFpointed at an attacker-controlled master is another.
Why “there’s nothing sensitive in the cache” is the wrong question
Section titled “Why “there’s nothing sensitive in the cache” is the wrong question”The attacker is not reading your cache. They are using your Redis as a file-writing primitive to get a shell on the host. What’s in the keyspace is irrelevant to that.
It follows that an empty, freshly installed, “just for testing” Redis on a public IP is exactly as dangerous as your production one. Possibly more, because nobody is watching it.
The shortest path from exposed to closed
Section titled “The shortest path from exposed to closed”In this order:
- Bind to a private interface — the listener stops existing on the public interface. This alone closes it.
- Require authentication with ACL users — the redundancy layer for when a network rule is wrong.
- Restrict dangerous commands — removing
CONFIGandMODULEfrom the application user removes the primitive itself. - Run as an unprivileged user — bounds what a successful write can reach.
Steps 1 and 2 take two minutes. Do them before you finish reading this page.
Related
Section titled “Related”- Hardening Redis and Valkey — the full checklist.
- Leave protected-mode on — the guard people disable right before this happens.