
Oct 20, 2025
Recent Vulnerabilities in Redis Server’s Lua Scripting Engine
Discover multiple Redis CVEs, including the critical CVE-2025-49844 — a 13-year-old use-after-free vulnerability in the Lua parser that can allow remote code execution and server crashes.
Multiple CVEs have been discovered in the Redis server, two of these CVEs are rated critical, leading to server crashes and potential remote code execution outside of the redis sandbox.
CVE-2025-49844 is a 13-year old use-after-free vulnerability, found in older versions of redis-server’s lua parser. The flaw arises from the lua parser and stack management code in the redis server. An authenticated attacker can send a crafted script to trigger garbage collection while the parser still references freed memory, producing a Use-After-Free that leads to native code execution.
- CVE ID: CVE-2025-49844
- Severity: Critical
- CVSS Score: 9.9
- EPSS Score: N/A
- Impact: Remote Code Execution
- Attack Vector: Network
- Authentication Required: Yes
- Vulnerable Component: luaY_parser function in lparser.c
CVE-2025-46817 is an integer overflow vulnerability in redis’s lua unpack function. An authenticated attacker can send a crafted lua script to unpack extreme values, causing an integer flow that can corrupt the stack, leading to potential remote code execution.
- CVE ID: CVE-2025-46817
- Severity: Critical
- CVSS Score: 9.8
- EPSS Score: N/A
- Impact: Stack Corruption/Potential Remote Code Execution
- Attack Vector: Network
- Authentication Required: Yes
- Vulnerable Component: luaB_unpack function in lbaselib.c
CVE-2025-46818 is a privilege escalation vulnerability where an authenticated attacker can send a crafted lua script to modify basic type metatables that should be read only, giving them the ability to inject code for other users to execute.
- CVE ID: CVE-2025-46818
- Severity: High
- CVSS Score: 7.3
- EPSS Score: N/A
- Impact: Redis Privilege Escalation
- Attack Vector: Network
- Authentication Required: Yes
- Vulnerable Component: scriptingInit function in eval.c, and luaEngineInitEngine function in function_lua.c
Technical Breakdown
In the luaY_parser function in the lparser.c file for Redis’s lua parser, the function adds a new Tstring object into the lexer without any additional protections. If the attacker then triggers garbage collection through the collectgarbage(‘collect’) function call while Redis’s lua parser is parsing the Tstring object, then after the garbage collection frees the Tstring object, the parser will continue to reference the freed string, causing a use-after-free on the Tstring object that the attacker can control. The attacker can then use this to execute code outside of Redis’s lua interpreter sandbox, leading to code execution on the host.
Additionally, in the luaB_unpack function in the lbaselib.c file for Redis’s lua engine, the function calculates the number of elements to unpack, n ,by computing n = e – i + 1, without casting values e or i as an unsigned integer. Attackers can therefore carefully craft a table to unpack where the e – i + 1 overflows, causing the lua engine to unpack a significantly higher amount of values than the size of the tables, leading to stack corruption, server crash, and potential remote code execution on the host.
Finally, when Redis’s lua scripting engine is initialized, it does not set basic type metatables, such as strings, booleans, etc. to be read only. The attacker can then write to the metatable to point to a lua function of their choosing. If another elevated user triggers the edited metatable, then they will execute the attacker injected lua code with the permissions of the elevated user, giving the attacker the ability to escalate privileges within redis.
- The attacker must be able to authenticate to the redis server
- The redis server must have lua execution enabled
- The version of redis must be less than 8.2.2, 8.0.4, 7.4.6, 7.2.11, or 6.2.20
As of the time of this post, there are no current PoCs available that will give users remote code execution on the redis server. However, there are PoCs available for all 3 CVEs that will result in either memory corruption, or a crash, which are both good starting points for exploitation.
For CVE-2025-49844, the use after free will trigger when garbage collection happens during the execution of the parser function. This may take multiple attempts to trigger. First, an attacker will need to create memory pressure, in order to get the lua parser to create memory chunks that will be garbage collected. An attacker can do that with the string.rep function, to create massive strings:
local a = string.rep(‘asdf’, 65536) -- or any larger number here
Afterwards, the attacker will need to interweave garbage collection, with the collectgarbage(‘collect’); return gc; code snippet, and large script parsing, which can be done by building a large lua script string, and running loadstring() with the large script string to compile and parse the script. Repeat the above enough times, and the attacker should be able to get the time where garbage collection happens while luaY_parser is busy parsing the large script string, causing a crash from the use after free.

For CVE-2025-46817, the integer overflow will trigger with the following lua script:
return unpack({‘a’,’b’,‘c’}, -1, 2147483647)
This will cause the stack size calculation to wrap back to a small value, enabling redis’s lua engine to attempt unpacking significantly more values than the input array of {‘a’, ‘b’, ‘c’}. Redis will then try to return all these values from the unpacked result, resulting in memory being exhausted from the redis server, leading to a redis server crash.

Finally, for CVE-2025-46818, the attacker can test whether or not they have control of the metatable by running the following lua script in Redis:
getmetatable(“”).__index = function(_, key)
if key == “testfunc” then
return function()
return “testfuncoutput”
end
end
End
This script edits the string metatable so that anyone who executes the testfunc function for a string will execute attacker controlled code, in this case the return “testfuncoutput” line. If an user runs the following lua script:
return (‘teststring’).testfunc()
Then they will get the output “testfuncoutput”, which is the attacker injected code. Note that the “testfunc” key could be replaced with whatever name the attacker chooses, giving the attacker the ability to inject code to arbitrary metatables, which could lead to privilege escalation if another user decides to execute the injected metatable.
Try Hands-On
You can try exploiting these vulnerabilities in a controlled environment via the OffSec Offensive Cyber Range lab for CVE-2025-49844.
- Update the redis server to the latest version
- Enable protected mode on the redis server
- Enact ACLs to disable Lua execution for untrusted users.
- Enforce authentication on the redis server.
- Restrict outbound access from the server to prevent reverse shells or external payload fetching.
- NVD Entry for CVE-2025-49844
- CVE Details for CVE-2025-49844
- NVD Entry for CVE-2025-46817
- CVE Details for CVE-2025-46817
- NVD Entry for CVE-2025-46818
- CVE Details for CVE-2025-46818
- Wiz RediShell Critical Remote Code Execution vulnerability in Redis Server
- PoC Redis Lua Parser Use-After-Free
- PoC Redis Lua Engine Unpack Integer Overflow
- PoC Redis Lua Sandbox Cross User Escape
Stay in the know: Become an OffSec Insider
Get the latest updates about resources, events & promotions from OffSec!