Redis’ Lua scripting subsystem contained a subtle but consequential weakness that let a less‑privileged user inject code which could later execute with the privileges of a higher‑privileged Redis user — a bug tracked as CVE‑2022‑24735 and fixed in Redis 6.2.7 and 7.0.0.
Background / Overview
Redis has supported embedded Lua scripting since 2.6 as a lightweight way to run small pieces of logic atomically on the server. Scripts can be executed with EVAL, EVALSHA or preloaded into the script cache with SCRIPT LOAD and then invoked with EVALSHA. Scripts are cached in memory for the lifetime of a server process (until SCRIPT FLUSH or restart), and scripts are often treated like persistent, in‑memory “commands.” Starting with Redis 6.0 the server introduced an ACL (access control list) model that allows multiple users with different command permissions. That security model change — useful for multi‑tenant or multi‑role deployments — made pre‑existing Lua interpreter behaviors, which were previously harmless in single‑user deployments, exploitable in the context of multiple users with different privileges. The vulnerability CVE‑2022‑24735 specifically arises when weak boundaries in the Lua execution environment allow an attacker who can upload or run Lua code while authenticated as a low‑privileged user to
persist or
plant code that will later run under a higher‑privileged user’s execution context. The Redis maintainers published an advisory and shipped fixes in the 6.2.7 and 7.0.0 releases.
How Redis scripting and ACLs interact (technical primer)
Redis exposes a small but powerful Lua runtime to let clients run short server‑side programs synchronously. Important behavioral points:
- EVAL executes a literal Lua script and registers it in the instance’s script cache; EVALSHA invokes a cached script by its SHA1 digest. SCRIPT LOAD places a script in that cache without executing it. The cache is process‑local and persists until SCRIPT FLUSH or a server restart.
- With ACLs, commands (including EVAL / SCRIPT) can be selectively allowed or denied for each user. ACL rules therefore are a primary mitigation tool to restrict scripting.
- Historically, the way Redis wrapped and handled user Lua code, and the structure of global tables available to scripts, meant a clever script could influence the interpreter's global state or rely on behaviors that permitted code execution during script compilation or that let one user influence another user’s script execution context.
These properties are central to understanding the vector exploited by CVE‑2022‑24735: script caching and global state, combined with a permissive Lua environment, let a low‑privileged actor inject payloads that could later run with higher privileges when a privileged user invoked scripts.
What went wrong — deep dive into CVE‑2022‑24735
The vulnerability is best understood as a class of
code‑injection / global‑state manipulation in the embedded Lua environment. The Redis engineering team summarized the root causes and their corrective approach in a dedicated pull request and advisory:
- Redis previously wrapped user code into a global function name derived from the script SHA (for example f_<sha>) and stored that function on the global table. Because the function lived in a global namespace, another user’s script could override or tamper with that global, or crafted code injected during the compile phase could execute outside the intended context. That meant a malicious low‑privilege script could insert or alter global state that later ran in a more‑privileged context.
- The implementation let user code execute at compile time in ways that were not fully isolated: a script could craft data that executes during the wrapping/compiling phases, creating a path for code to run outside the expected sandboxed context.
- Because scripts are cached and persist until explicit flush/restart, an attacker who could get a script into the cache could influence subsequent executions, even if those were triggered by other users.
To remediate these weaknesses the Redis team applied multiple coordinated fixes in the codebase:
- Introduced the concept of readonly tables into the Lua environment and exposed an internal API to make certain tables immutable during script load and execution. That prevents script authors from altering core global objects or metatables that other scripts rely on.
- Moved user functions into the Lua registry (a private table not accessible to user scripts) instead of saving them on the public global table. This removes the attack surface of other users overwriting or hijacking the f_<sha> entries.
- Protected globals via metatables and an explicit allow‑list for the API provided to scripts; initialization and library setup are done under controlled conditions and then the tables are frozen so that runtime writes are prevented.
These fixes were merged by April 27, 2022 and backported into the stable release lines cited above.
Impact and exploitability: what the scores and advisories say
The public advisories classify CVE‑2022‑24735 as a
Low severity issue with a CVSS v3.1 base score of 3.9 and the following characteristics: local attack vector, low attack complexity, low privileges required, and user interaction required. The official GitHub security advisory published by the Redis project lists the vulnerability, its impact statement, and the patched versions. Independent trackers (OSV, Linux distribution advisories, AWS ALAS and others) corroborate the affected versions and the remedial releases and repeat the recommended workaround that — if scripting is not required — administrators can mitigate risk by blocking SCRIPT and EVAL commands with ACL rules until they can apply a binary patch. A few practical takeaways from the published metadata:
- Preconditions: an attacker must be able to authenticate to Redis as a user who is permitted to run or load scripts — this is not a purely unauthenticated remote exploit.
- Persistence: because scripts are cached in process memory and can survive across invocations, an injection placed in the cache can be leveraged later when higher‑privileged actors run scripts.
- No public weaponized PoC tied to mass exploitation was published at the time these advisories were written; public trackers mark exploit code as unknown. That reduces but does not remove the practical risk, especially in environments where multiple users share a server or where lower‑privileged tenants run untrusted workloads.
Who should care — realistic risk scenarios
CVE‑2022‑24735 is not a generic “remote root” bug you can trigger over the public internet without credentials, but it is dangerous in specific, realistic deployment models:
- Multi‑tenant deployments where different applications or teams share a single Redis instance and where some users have script privileges while others do not. A tenant that can upload or run scripts could plant a payload that later executes when an administrative or privileged automation routine runs.
- Managed hosting or platform‑as‑a‑service setups where provider or administrative jobs run periodically with higher privileges, and where untrusted customers may be able to push a script into the cache. The attack can be practical if the attacker’s account can run SCRIPT LOAD or EVAL.
- Development, CI, or build environments that use a single shared Redis for ephemeral tasks: build agents or test harnesses often run automation that may invoke scripts with elevated access; an attacker who can commit a malicious script into the cache can persist a backdoor for later automation runs.
The risk is lower for single‑user, well‑isolated deployments where the only accounts capable of scripting are trusted service accounts and there’s strict network and authentication control.
Mitigation: patches, ACLs and practical hardening steps
The primary remediation is straightforward: upgrade to a fixed Redis build. The fix is included in Redis 6.2.7 and 7.0.0 and later releases; apply vendor packages for your distribution or the upstream redis‑server binary as appropriate. If immediate patching is impossible, a practical workaround is to disable Lua scripting for untrusted accounts by adjusting ACL rules to block the EVAL and SCRIPT families of commands. Redis’ ACL system supports allowing or blocking commands and specific subcommands; administrators can deny the following commands and subcommands to untrusted users: EVAL, EVALSHA, SCRIPT, SCRIPT LOAD, SCRIPT FLUSH, SCRIPT KILL. The exact ACL syntax depends on your Redis version, but an example (illustrative) rule to block scripting for a user named limited-user would look like:
- ACL SETUSER limited-user on >somepassword -eval -evalsha -script -script|load -script|flush -script|kill
This example removes the listed commands from the user’s allowed command set. Test ACL updates in a staging environment before applying them in production and prefer an explicit deny for scripting rather than a blind “-@all” approach to avoid accidentally removing essential operational commands. Use the official ACL docs and test commands to validate your configuration. Additional recommended steps:
- Inventory and prioritize:
- Identify all running Redis instances, their versions, and whether EVAL/SCRIPT or SCRIPT LOAD are used in production flows.
- Prioritize multi‑tenant or publicly accessible instances for immediate action.
- Patch plan:
- Apply the vendor‑provided fixed release (6.2.7 / 7.0.0 or later) to test environments, validate application behavior, then roll to production.
- Short‑term containment:
- If you cannot patch immediately, use ACLs to block scripting for untrusted users and disable scripting entirely for accounts that do not legitimately need it.
- Consider flushing the server script cache if you identify suspicious script hashes (use SCRIPT FLUSH) — but be aware of application dependencies on cached scripts and coordinate restarts.
- Monitor and hunt:
- Log and alert on SCRIPT LOAD, EVAL and EVALSHA calls from accounts that shouldn’t use them.
- Use Redis monitoring/command‑logging offered by your platform or external observability tooling to track anomalous script operations.
- Long‑term hygiene:
- Avoid single shared Redis instances for distinct trust boundaries; prefer per‑application or per‑tenant instances.
- Harden network access (bind to localhost, use firewall rules, restrict client networks), enable AUTH and TLS where supported, and enforce strong secrets for ACL users.
Detection and incident response: what to look for
Detection focus should include both proactive and retrospective indicators:
- Command telemetry: watch for SCRIPT LOAD and EVAL calls and the originating authenticated user and client IP. Any unexpected invocations from low‑privileged accounts are a red flag.
- Script cache inspection: if you suspect compromise, use SCRIPT EXISTS / SCRIPT FLUSH to inspect or remove cached scripts. Note that SCRIPT FLUSH will remove all cached scripts — coordinate with application owners because this can break legitimate uses.
- Authentication logs and ACL changes: audit who created or modified ACL users or changed their permissions. An attacker who gained access may have attempted to elevate privileges by creating permissive users.
- Cross‑system indicators: because this flaw requires credentials or an authenticated session, hunt for suspicious logins, credential theft, or lateral activity in your environment as part of a broader incident response.
Critical analysis — strengths of the fix and residual risks
Strengths
- The Redis maintainers addressed the bug with code‑level sandboxing changes rather than making only a configuration workaround. Moving user code into the Lua registry and introducing readonly tables provide a principled, durable protection against this class of attack. The patches were merged and backported to stable release lines quickly.
- The advisory and the patch process are transparent: upstream PRs describe the design and the developer rationale, which makes auditing and backporting by distributors possible.
Residual risks and operational tradeoffs
- Backward‑compatibility / application impact: the fix changes Lua runtime semantics in subtle ways (for example, the PR notes removal of the print function and disallowing non‑local custom function definitions) that may break existing scripts that relied on previous behavior. Teams must test carefully, especially if they bundle complex Lua scripts.
- Patch adoption lag: many organizations consume Redis packaged by downstream distributions or managed services. If those vendors delay backports or if hosted Redis instances are not patched promptly, the window of exposure persists — especially for multi‑tenant environments. Distribution advisories (Red Hat, AWS ALAS, and others) show the same fix but with independent patch schedules; administrators must verify their own supply chain.
- Perception vs. reality of severity: the CVSS score classifies this issue as low, but severity metrics don’t always capture the operational context. In multi‑tenant scenarios where script permissions are widely granted, the practical impact can be significant despite the low base score. Treat the environment and trust boundaries as the true drivers of risk.
Unverifiable or commonly misunderstood claims
- Be cautious of any claim that this CVE implies immediate, unauthenticated remote takeover or denial of service without further context. The published advisories make clear that the attack requires authentication and scripting privileges; it is not a remote code execution vector that any unauthenticated actor can weaponize on its own. Any contrast between a general “total loss of availability” statement and the published CVE metadata should be treated as unrelated to this specific CVE unless the source explicitly ties them together.
Practical checklist for Windows and cross‑platform sysadmins
- Inventory: locate all Redis servers (hosted, on‑prem, containers, cloud) and note versions and which accounts have scripting permissions.
- Patch: schedule updates to Redis 6.2.7 or 7.0.0+ in test first, then production. Monitor downstream distro advisories for backported packages and update accordingly.
- Short‑term containment: if you cannot patch immediately, remove scripting permissions from untrusted users using ACLs, or block EVAL/SCRIPT commands wholesale for non‑trusted accounts. Test changes in staging.
- Audit and monitor: log scripting commands, alert on unexpected SCRIPT LOAD/EVAL activity, and correlate with authentication logs and network telemetry.
- Clean up: if you discover unauthorized scripts in cache, coordinate a safe SCRIPT FLUSH / restart after confirming dependencies, and rotate any credentials that may have been exposed.
- Architecture: plan to avoid shared Redis instances across trust zones; prefer instance segregation, and use managed services that offer per‑tenant isolation.
Conclusion
CVE‑2022‑24735 is a classic example of how evolving security models can reveal latent weaknesses: the addition of ACLs to Redis introduced a multi‑user security surface and exposed Lua runtime behaviors that were previously harmless. The Redis team’s fix — moving user functions into the private registry, introducing readonly tables and freezing global tables — closes the gap in a principled way, but operational risk remains until organizations patch and validate their deployments. For system administrators and platform operators the priority is clear: identify Redis instances where scripting is available, apply the fixed releases or vendor patches (6.2.7 / 7.0.0 or later), and, where patching cannot happen immediately, block SCRIPT/EVAL via ACLs and monitor for unexpected scripting activity. The technical fix reduces the attack surface; the operational controls and segregation reduce exposure. Taken together, those steps remove the practical avenues an attacker would use to elevate script execution privileges in shared or multi‑role Redis deployments.
Source: MSRC
Security Update Guide - Microsoft Security Response Center