16 ms·
An unexpected Redis sandbox escape affecting Debian-based distros
- goodpoint 5y agoUnbundling dependencies is a security feature.
- reginaldo 5y agoAuthor here, so feel free to ask me anything. I had to shrink the title in order for it to fit, but, as the first paragraph says, this affects only Debian and Debian-based distros, so it's a Debian bug, not a Redis bug.
- booi 5y agooof, and just for people who are curious but this affects Ubuntu / Ubuntu server as well being a Debian derivative.
- Fabricio20 5y agoIf I understand correctly this RCE is mostly a big concern to hosts that don't make use of redis authentication, as eval is locked behind it? Some quick testing on my end suggests the eval command is parsed before authentication check but requires authentication for execution, but I may be wrong here. In a perfect world we can all update immediately but when we still have some servers in Ubuntu 16.04..
- gunapologist99 5y agoMost people probably don't use Redis authentication, and most servers are configured to not require it (including the Debian/Ubuntu defaults).
- junon 5y agoMrh why does Redis include the package library? IMO packages should be loaded at boot via configuration. This is Lua hardening 101... Good writeup. Thank you.
- reginaldo 5y agoUpstream Redis doesn't. At least in my builds from upstream, luaopen_package and luaopen_os aren't even available on the binary. Debian does things differently, though. They need package in order to require the "json" and "bit" libraries, which are packaged separately on Debian. Another thing that would be interesting and affect upstream as well would be getting the "debug" package back from the redis error function.
- junon 5y agoOhhh okay I see. Wow :( Thanks for the clarification.
- trasz 5y agoSo it’s about escaping the sandbox around Lua interpreter, not escaping some sandbox Redis itself is running in?
- gmfawcett 5y agoRight -- you can escape the sandbox that Lua runs in, inside Redis, and get the Redis process' user to execute arbitrary code in its environment. Redis might be inside a hardened container, or running as a privileged account on a shared machine.
- luto 5y agoredis-server is just a plain executable. Unless you're putting it in a sandbox yourself - for example, using a VM or systemd features - redis has no sandbox. There is nothing to escape from. The Lua interpreter _within_ redis acts as a sandbox, which got a bit mangled here. Most features are not implemented in Lua, though. So this is only used for things like the EVAL command.
- qalmakka 5y agoYet another issue due to nonsensical Debian packaging policies. Debian should just stop wasting time applying random patches or modifying packages, if upstream is doing something there's probably a good reason for that.
- b112 5y agoBecause all of the issues they've genuinely fixed, security and otherwise, are meaningless. Or are you just basing this on <bad thing> happened, thus all other cases (hundred of thousands of patches) are wrong?
- josephcsible 5y agoThis isn't the only time Debian has introduced a serious security vulnerability by changing things in packages. The most notable prior example that comes to mind is CVE-2008-0166.
- gmfawcett 5y agoThat's a notable prior example from 14 years ago. I'm not sure you're making a strong argument here!
- pgporada 5y agoIt's still relevant for Web PKI work.
- yjftsjthsd-h 5y agoHow is it still relevant? Even if certs made with a vulnerable version weren't revoked at the time, wouldn't they would have been rotated by now?
- gunapologist99 5y agoAnother similar one (perhaps worse!) from the same era: https://jblevins.org/log/ssh-vulnkey https://jblevins.org/log/ssh-vulnkey
- josephcsible 5y agoWhy did Debian need to change Redis to link Lua dynamically in the first place?
- gspr 5y agoUnnecessary static linking is a Policy violation.
- blihp 5y agoDynamic linking is Debian's preferred approach. When it works as intended (which is usually), it's generally a good thing.
- infogulch 5y agoDon't you know? Dynamic linking is always better for security. This is a great example. With dynamic linking you can more quickly patch security holes caused by dynamic linking.
- rlpb 5y agoIf everything were statically linked, getting your daily security update would basically involve redownloading the entire distribution, since when a core component were patched everything would have to be rebuilt. This wouldn't be practical. Therefore, dynamic linking is the norm on binary distributions.
- unixbane 5y agoomg im gonna buy akamai products now
- mherrmann 5y agoDebian's unattended-upgrades is amazing. Just checked some of my boxes and they are already running the patched version.
- forty 5y agoThe only case I had problems with unattended upgrade was with redis... Both the master and the replica restarted at the same time, which caused some issues.
- benmmurphy 5y agoI think this is still 'broken' because Redis have applied custom patches to the Lua source code in order to prevent sandbox escapes. If Debian Redis is using the normal Lua then these patches will not have been applied. https://github.com/redis/redis/commit/49efe300af258e83f377cd8142d2c67d66fc2e3a https://github.com/redis/redis/commit/49efe300af258e83f377cd... and you can check the history on that file to see they haven't removed the fix: https://github.com/redis/redis/commits/unstable/deps/lua/src/ldo.c https://github.com/redis/redis/commits/unstable/deps/lua/src... it could be the latest lua version that Debian ships with has 'safe' byte code evaluation and this fix no longer needs to be applied.
- bawolff 5y agoGiven that lua is meant to be an embedded language, its kind of surprising this is neccesary.
- tedunangst 5y agoMaking an application scriptable doesn't always mean you want it to be scriptable by hostile adversaries.
- bawolff 5y agoThat's what i mean. For an embedded scriptable language, making something scriptable and sandboxed is a core use case. It is surprising to me that doing the thing lua is famous for requires source code mods.
- mikemike 5y agoYes, of course it's vulnerable, verified with Docker debian:sid. That was my first reaction when I read this, but I wanted to verify it first. You beat me with this post. Since you've already let the cat out of the hat (which is not ideal), please file the bugs at Debian and Ubuntu. Test command: redis-cli eval 'return select(2, loadstring("\027")):match("binary") and "VULNERABLE" or "OK"' 0 While we're at it, redis has ignored the advice at: http://lua-users.org/wiki/SandBoxes http://lua-users.org/wiki/SandBoxes Almost all of the critical functions (loadstring, load, getmetatable, getfenv, ...) are present and unprotected in the redis 'SandBox' (which isn't). Which means, disable scripting or shut down your redis instances NOW, which do not run with the same privileges as any client which has access to this. Scripting can be disabled by renaming the EVAL and EVALSHA commands to unguessable names.
- gunapologist99 5y agoDoes Redis upstream still bind to all addresses by default on startup, or only to localhost? One nice thing is that some years ago, Debian/Ubuntu configured the default config to only bind to localhost. (You can change it, but only if you need to, so it's "default secure" instead of "default insecure".) That can really hurt, especially since you might build it and start it up for testing from within your personal user account (maybe just to benchmark a new server -- and perhaps you have sudo?), and then: boom, that entire machine is now pwned. Binding to all interfaces by default is definitely not the wisest design decision when you could just bind to localhost and then let people bind to 0.0.0.0 as they like, but you still see some naive devs doing it even on new software (like seaweedfs.) Even Mongodb doesn't do that anymore.
- ptx 5y agoIs this sandbox intended as a security feature? According to the Redis documentation [1], "The sandbox attempts to prevent accidental misuse [...] Scripts should never [...] attempt to perform any other system call other than those supported by the API". (Also "reduce potential threats", but that doesn't sound like the primary purpose or a particularly strong claim of security.) [1] https://redis.io/topics/programmability https://redis.io/topics/programmability
- tedunangst 5y agoI think your edits are mangling the intended meaning of the quote. Your script should not try to perform other system calls, because it won't work.
- ptx 5y agoBut does "it won't work" mean "don't try this in your app" or does it mean that the system can be expected to safely run arbitrary untrusted code? The documentation makes it sound like it's primarily intended to guide people towards using the API correctly. Here is the whole section for context: > Redis places the engine that executes user scripts inside a sandbox. The sandbox attempts to prevent accidental misuse and reduce potential threats from the server's environment. > Scripts should never try to access the Redis server's underlying host systems, such as the file system, network, or attempt to perform any other system call other than those supported by the API. > Scripts should operate solely on data stored in Redis and data provided as arguments to their execution.
- mikemike 5y agoThat's what I'm wondering, too, right now. It's trivial to DoS-hang redis with the script feature (and SCRIPT KILL won't help). And I found at least 3 DoS-crash, because it hasn't backported fixes to its copy of Lua 5.1.5 (but Debian's liblua 5.1 might -- I haven't checked). And that's without even exploring the really problematic builtins it still has available. Maybe they should instead clarify their security guarantee for redis scripting (e.g. "none").