Vulnerabilities
7 min readUpdatedRediShell (CVE-2025-49844): the Redis Lua use-after-free
Quick answer
RediShell, CVE-2025-49844, is a use-after-free remote code execution flaw in the Lua scripting engine of Redis. An authenticated client could run a crafted Lua script that manipulates the garbage collector, escapes the sandbox and runs native code on the host. It scored CVSS 10.0 per Redis, was disclosed on 3 October 2025, and had existed for thirteen years. It affects every Redis version with Lua scripting; fixes are 8.2.2, 8.0.4, 7.4.6, 7.2.11 and 6.2.20. Never expose Redis to the internet.
At a glance
critical severity- Identifier
- CVE-2025-49844
- Also known as
- RediShell
- Product
- Redis (all editions with Lua scripting)
- Affected
- All versions with Lua scripting, up to and including 8.2.1
- Fixed in
- 8.2.2; 8.0.4; 7.4.6; 7.2.11; 6.2.20
- CVSS
- 10.0 (Redis advisory) / 9.9 (CVSS 3.1, GitHub CNA and NVD)
- Disclosed
- Known exploited (CISA KEV)
- Not listed
Patched. Redis reported no evidence of exploitation at disclosure; not in CISA KEV. Patch and restrict access.
01What is RediShell (CVE-2025-49844)?
RediShell is a use-after-free bug in the Lua scripting engine built into Redis. A client that can run Lua — through EVAL, EVALSHA or a loaded function — could send a crafted script that manipulates the garbage collector into freeing memory that is still in use, then reuse that dangling reference to escape the Lua sandbox and execute native code in the Redis server process. From there an attacker can read data, steal credentials on the host, or move laterally.
Redis's advisory rates it CVSS 10.0; the CVE record and NVD list 9.9. The flaw had been present in the source for about thirteen years, affecting essentially every Redis release with Lua scripting. Wiz researchers reported it at Pwn2Own Berlin on 16 May 2025, and it was patched on 3 October 2025. The one precondition is the ability to run a script, which brings the configuration of your Redis directly into the risk picture.
02Affected and fixed versions, and the companions
RediShell shipped alongside three companion Lua bugs disclosed the same day, all fixed in the same releases. Further memory-safety bugs with RCE potential followed from November 2025 into 2026, most of them reachable through scripting or the RESTORE command, and were fixed in the 8.x and back-ported lines. Get onto a current patch level for your line and keep moving as the follow-ups land.
| CVE | Issue | Fixed in |
|---|---|---|
| CVE-2025-49844 (RediShell) | Lua use-after-free → RCE | 8.2.2, 8.0.4, 7.4.6, 7.2.11, 6.2.20 |
| CVE-2025-46817 | Lua integer overflow → RCE | 8.2.2, 8.0.4, 7.4.6, 7.2.11, 6.2.20 |
| CVE-2025-46818 | Lua script runs as another user | 8.2.2, 8.0.4, 7.4.6, 7.2.11, 6.2.20 |
| CVE-2025-46819 | Lua out-of-bounds read / DoS | 8.2.2, 8.0.4, 7.4.6, 7.2.11, 6.2.20 |
| CVE-2025-62507 | XACKDEL stack overflow → possible RCE (8.2 and newer) | 8.2.3 |
| CVE-2026-23479 / -23631 | Use-after-free (unblock flow; Lua on writable replicas) | 8.6.3, 8.4.3, 8.2.6, 7.4.9, 7.2.14 |
| CVE-2026-25243 | RESTORE invalid memory access → RCE | 8.6.3, 8.4.3, 8.2.6, 7.4.9, 7.2.14, 6.2.22 |
| CVE-2026-66373 | Stream RESTORE double-free → RCE (incomplete fix of 25243) | 8.6.5, 8.4.5, 8.2.8, 7.4.10, 7.2.15, 6.2.23; 8.8.0 |
03How an attack works, conceptually
The attacker needs a connection that can run a script. They send a Lua script engineered to drive the garbage collector into freeing an object that the engine still references, then act through that freed reference to corrupt memory and break out of the sandbox into the host process. The companion bugs and later follow-ups reach similar ends through an integer overflow, a user-context confusion, or malformed input to the RESTORE command.
The decisive factor is reachability. If your Redis is bound to localhost or a private network and requires strong credentials, an external attacker has no connection on which to send a script in the first place. If it is exposed to the internet — especially with the default container configuration, which does not require authentication — then the precondition is trivially met. Configuration, not the bug alone, is what determines whether you are exploitable.
04How to check if you are affected
Two questions matter: is the version below the fix for your line, and can anyone reach it without authentication? An instance that is unpatched but bound to localhost with a strong password is far less exposed than a patched instance listening on a public address with nopass. Check both, and fix exposure first if it is wrong.
# Version (compare against the fixed releases for your line)
redis-server --version
redis-cli INFO server | grep -E '^(redis_version|os):'
# Is it listening only on localhost / a private address?
ss -ltnp 'sport = :6379'
redis-cli CONFIG GET bind
redis-cli CONFIG GET protected-mode
# Does the default user require a password?
redis-cli ACL WHOAMI
redis-cli ACL LIST # look for 'nopass' on the default user05How to fix and harden Redis
Upgrade to the newest release of your line — 8.2.2, 8.0.4, 7.4.6, 7.2.11 and 6.2.20 are only the minimums for RediShell — and then harden, because Redis's own advisory notes that exploitation first requires authenticated access to the instance. The single most important control is network isolation: Redis should almost never be reachable from the public internet. Beyond that, require authentication, and use ACLs to deny scripting and dangerous commands to any user that does not need them.
- Never expose Redis directly to the internet; bind it to localhost or a private network and firewall port 6379, which belongs on the never-public list of ports
- Leave protected-mode on and set strong credentials with requirepass or, better, per-user ACLs
- Deny scripting to users that do not need it with -@scripting (covering EVAL, EVALSHA and FUNCTION), which closes the whole Lua family
- Restrict RESTORE, CONFIG, REPLICAOF and other -@dangerous commands to a dedicated admin user only
- Run Redis as a non-root user so a successful escape yields the least possible on the host
# redis.conf: keep Redis off the internet first (these are the upstream defaults)
bind 127.0.0.1 -::1
protected-mode yes
# At the redis-cli prompt, as an admin user, on one line. The app user can read and
# write its own keys but cannot run scripts or @dangerous commands (RESTORE, FLUSHALL, CONFIG ...).
# Rules apply left to right, so the deny rules must come last.
# ACL SETUSER appuser on >REPLACE_WITH_STRONG_SECRET ~app:* +@read +@write -@scripting -@dangerous
# Then give the default user a password or disable it (no nopass in production).06What a WAF or reverse proxy can and cannot do
This is where honesty matters most. Redis speaks its own protocol (RESP), not HTTP, so a web application firewall and an HTTP reverse proxy have nothing to inspect — they sit in front of your website, not your datastore, and never see Redis traffic. No edge rule filters a Lua script or a RESTORE payload. Any claim that a web firewall "protects Redis" is misplaced.
The controls that work are network and identity controls: keep the datastore private, authenticate every client, and apply least-privilege ACLs. A proxy such as GuardX protects the public web tier in front of an application, and keeping your origin's real address hidden reduces the chance that an attacker maps your backend network at all. That is perimeter obscurity, though — it is not protection of the datastore itself. Patch it and lock it down directly.
| Control | Protects Redis? | Why |
|---|---|---|
| Web application firewall | No | Redis is not HTTP; a web WAF never sees its protocol |
| Network isolation / firewall | Yes | Removes the attacker's connection entirely |
| Authentication + ACLs | Yes | Denies the precondition — the ability to run a script |
| Running patched Redis | Yes | Removes the memory-safety bug |
07Disclosure timeline
A thirteen-year-old bug in default-reachable software is a reminder that exposure is the real risk multiplier. The fix is a quick upgrade, but the lasting protection is the posture: Redis on a private network, authenticated, with scripting and dangerous commands denied to everyone who does not need them. Treat the next disclosure as a given and keep that posture in place, the same way you keep attack protection always on.
| Date | Event |
|---|---|
| 16 May 2025 | Wiz researchers report it to Redis at Pwn2Own Berlin |
| 3 Oct 2025 | Fixes released; disclosed as CVE-2025-49844 and three companions |
| 6 Oct 2025 | Wiz publishes its write-up with exposure figures |
| 2 Nov 2025 | XACKDEL stack overflow (CVE-2025-62507) fixed in 8.2.3 |
| 5 May 2026 | Follow-up memory-safety RCEs fixed in 8.6.3 and back-ports |
| 23 Jul 2026 | Stream RESTORE double-free (CVE-2026-66373) fixed in 6.2.23 to 8.6.5 |
| 17 Aug / 17 Sep 2026 | Further security releases, including an RDB-loading RCE fix |
Questions
Frequently asked questions
Sources
Sources and verification
The bind and protected-mode lines were checked against the upstream redis.conf (8.2 branch) and the ACL categories against the Redis ACL documentation; the ss filter was run with iproute2 6.1 on Debian 12, October 2026. redis-cli is not installed on the test host, so the redis-cli and ACL SETUSER lines were not executed and are illustrative reference syntax.
- 01NVD — CVE-2025-49844 · NVD
- 02GHSA-4789-qfc9-5f9q — Lua Use-After-Free may lead to RCE · GitHub Security Advisories
- 03Security Advisory: CVE-2025-49844 · Redis
- 04Wiz Research: RediShell — Critical Redis RCE (CVE-2025-49844) · Wiz
- 05Redis ACL documentation · Redis
- 06GHSA-c8h9-259x-jff4 — RESTORE invalid memory access · GitHub Security Advisories
- 07GHSA-jhjx-x4cf-4vm8 — XACKDEL stack overflow (CVE-2025-62507) · GitHub Security Advisories
- 08NVD — CVE-2026-66373 · NVD
- 09Redis release notes (security releases per line) · Redis
- 10redis.conf (8.2 branch, bind, protected-mode and command-renaming notes) · Redis
Last updated