Five ways it finds your Redis
// tool: redis_reconThese are complementary on purpose, because real deployments hide Redis differently. A single-VM or docker compose box publishes it right next to the app. A well-run one binds it to loopback where nothing outside can reach it — but the app can, and so can anything the app fetches for you. And almost every app, run either way, tells you where it lives if you read its config or its errors.
// 1 — THE APP NAMES IT (PIVOT)
A leaked dotenv, config page, build manifest or actuator dump. Every endpoint named is recorded and then probed. Loopback is rewritten to the scanned host — localhost in your config means your machine, not the scanner's.
// 2 — AN ERROR NAMES IT
Handled or unhandled — NewScan reads the whole probe log, not just 500s, because a cache outage is usually caught and returned with a 200.
// 3 — THROUGH THE APP (SSRF)
A curl-backed fetcher speaks dict://, which writes the URL path to the port as a line of text — Redis reads it as a command. This is the arm that reaches a loopback-bound Redis no port scan can see. In-band: the proof is Redis' own reply, so no collaborator is needed and it stays in the free tier.
// 4 — THE HOST'S OWN PORTS
One bounded connect each, on the machine you asked NewScan to scan. Scope is enforced by the scan's own scope lock: an endpoint your app discloses on a host that isn't in scope is reported, never probed.
// 5 — SERVERLESS: THERE IS NO PORT AT ALL
Upstash and Vercel KV are reached over HTTPS with a bearer token instead of over 6379 with a password, so every network check ever written is blind to them: the token is the entire security boundary — and it ships to the browser whenever the SDK is called from a client component or the env var gets a public prefix. NewScan records it only after the token authenticates, then establishes whether it can write using EXPIRE on a key that does not exist — write permission proven, nothing created or changed. A write-capable token in client code is total control of the cache; a read-only one is reported a step lower, because Upstash documents that as the supported pattern.
// WHY THIS STAYS FALSE-POSITIVE-FREE
Every finding on this page requires a Redis that answered without a credential. A password-protected instance replies -NOAUTH to every command and is recorded as safe — nothing is written about it at all. There is no guessing from a banner, no inference from an open port: the audit reports the values the server itself returned.
The read-only audit
// one round trip, nothing writtenWhen something answers unauthenticated, NewScan pipelines one batch of read commands and reports what comes back. COMMAND INFO is how it checks whether the dangerous commands still exist under their real names without ever running them — a renamed or ACL-blocked command answers nil.
| What it reports | Why it matters | Severity |
|---|---|---|
| Unauthenticated Redis / Sentinel | The whole keyspace is readable and writable by anyone who can reach the port — sessions, carts, queued jobs, cached PII. The evidence carries the live key count, so "an empty test instance" and "your production cache" don't read the same. | high |
| RCE primitives still exposed | CONFIG, MODULE and SLAVEOF/REPLICAOF under their real names is the documented path from "no password" to code running as the Redis user — CONFIG SET dir + dbfilename writes a file wherever it can, and the finding names the actual working directory. If that directory is one a web server publishes, it says so: the short version of this chain is a webshell. | critical |
| Exploit preconditions reachable | Every Redis memory-corruption RCE of 2024–2026 is post-authentication — which on an instance with no authentication means anyone. So the audit also reports whether the commands those chains need are available: RESTORE (the RESTORE and module corruption CVEs), EVAL/SCRIPT/FUNCTION (every Lua use-after-free, RediShell included), XGROUP (the Streams chain). That turns "your version is in range" into "and the way in is open". | critical |
| Destructive commands reachable | FLUSHALL/FLUSHDB erase every key and DEBUG can stall or crash the server — an availability and data-loss exposure even where the RCE chain is blocked. | medium |
| Known vulnerable version | The version read from INFO is cross-referenced against the offline advisory dataset — see the CVEs below. Only fires on a version it actually read. | critical |
| Vulnerable module | RediSearch, RedisTimeSeries and RedisBloom ship their own RCE advisories on their own version line, so a fully patched server with a stale module is still exploitable. MODULE LIST returns each module's version as a packed integer (21010 → 2.10.10); NewScan unpacks it and matches the module advisories separately. | high |
| Writable replica | replica-read-only no is the exact precondition for CVE-2026-23631 (a Lua use-after-free through master–replica sync), and a writable replica is a data-integrity problem in its own right. | reported |
| Cleartext transport | tls-port 0: commands, AUTH passwords and values cross the network readable by anyone on-path. Reported for remote endpoints, not for a loopback one where it is not a transport risk. | low |
Leaked connection strings
// tool: scan_sensitive_dataAny leaked redis:// URI is reported as a disclosed connection string. A separate, higher-signal finding fires only when the URI actively weakens transport security — because Redis AUTH sends the password in cleartext.
// FLAGGED
The last one needs no credential to be a finding: a managed endpoint — ElastiCache, Upstash, Azure Cache, Redis Cloud, Aiven — is reached across a network by definition, so plaintext there is in-transit encryption switched off on a hosted database. Most compliance frameworks treat that as a control failure.
// NOT FLAGGED (ON PURPOSE)
Plain redis:// inside a private network is how nearly every Redis runs. Flagging it would be noise, not a finding — so it isn't flagged. The endpoint is still recorded and probed.
Injection into the Redis command line
// tool: test_redis_injectionRedis separates commands with CRLF. A client that builds a command by string concatenation — or a codec that doesn't neutralise CRLF in a value, as Netty's Redis encoder did not (CVE-2026-42586) — lets a user-controlled cache key close the intended command and append another one. An ordinary web parameter becomes unauthenticated control of the datastore.
// WHAT AN ATTACKER SENDS
// WHAT NEWSCAN SENDS INSTEAD
// REFLECTION IS NOT EXECUTION
Plenty of endpoints echo their input, and a naive check would call every one of them vulnerable. So a different canary is sent first with no CRLF at all, and every echoed form of the payload is subtracted from the response before the verdict. A canary that survives that subtraction could only have been produced by Redis answering the injected command. An endpoint that merely reflects what you send is never flagged.
Consoles in front of it
// tool: probe_unauth_interfacesA management UI left open is unauthenticated access to the data behind it, with a nicer interface than redis-cli. Each is confirmed by the console's own fingerprint in the response — never by a bare 200.
REDIS COMMANDER
A full browser client for the instances it is wired to: read every key, edit or delete them, flush a database, run commands.
REDISINSIGHT
Redis' own GUI — browses and edits the keyspace, runs arbitrary commands from its CLI panel, and stores the host, port and password of every database added to it.
CELERY FLOWER
Every worker and task of the queue behind it: task arguments (routinely PII, tokens, internal ids) plus worker control — shutdown, pool resize, task revoke.
Why "just rename CONFIG" isn't a fix
// tool: correlate_findingsThe usual advice for an exposed Redis is to restrict the dangerous commands. That closes the cache's own route to code execution — and leaves the shorter one open, because your application reads values back out of that cache and rebuilds objects from them. Write one poisoned session, cache entry or queued job and the app does the rest. It is how a compromised Redis became a compromised GitLab.
RAILS
Marshal.load
Sessions and cache values are marshalled. Unmarshalling attacker bytes instantiates arbitrary objects.
DJANGO · FLASK · CELERY
pickle
Still the default serializer for a cache or broker payload that isn't a plain string. Unpickling executes code by design.
LARAVEL · SYMFONY
unserialize()
Queue and session payloads are PHP-serialized, reaching whatever POP gadget chain the installed packages provide.
SPRING · JAVA
JDK serialization
Spring Session's default Redis serializer, so a poisoned session value is deserialized straight into Java objects.
// NEITHER HALF KNOWS ABOUT THE OTHER
The Redis finding doesn't know what framework you run; the framework fingerprint doesn't know your cache is open. NewScan makes the join at the end of the scan and states the consequence, so the exposure is triaged as remote code execution rather than data exposure. Node and Express are deliberately excluded — they JSON.parse what they read, which constructs no objects and calls no methods, so there is no gadget chain. Claiming otherwise would make the finding untrue for the most common Redis stack there is.
On a network scan
// tool: datastore_exposurePoint NewScan at a subnet instead of a URL and the same audit runs across every host it maps — Redis alongside Memcached, Elasticsearch and MongoDB. Reachability is the start of the finding, not the end of it: what the instance allows is what gets reported.
Recent Redis security issues
// why these checks matterEvery one of these is post-authentication — and that is precisely why the unauthenticated finding above is severity-high on its own. An instance with no password hands every one of these chains to anyone who can reach the port. Each links to our page for that CVE, generated from the same advisory data the scanner matches against.
CVE-2025-49844 · CVSS 10.0
"RediShell" — Lua use-after-free
The maximum-severity Redis flaw: a crafted EVAL script manipulates the Lua garbage collector, escapes the sandbox and runs code on the host. Every build with Lua scripting is affected. Fixed in 7.2.11 / 7.4.6 / 8.0.4 / 8.2.2.
Our CVE page →
CVE-2026-25243 · May 2026
RESTORE invalid memory access
One of five patched together in May 2026, four of them RCE. A crafted serialized payload to RESTORE corrupts memory. It needs the RESTORE command — which is exactly what the audit above reports on.
Our CVE page →
CVE-2024-51737 · module
RediSearch integer overflow → RCE
A crafted LIMIT or KNN argument overflows into a heap overflow. Module CVEs track the module's version, so a fully patched server with a stale RediSearch is still exploitable — which is why MODULE LIST is part of the audit.
Our CVE page →
CVE-2025-32023
Hyperloglog out-of-bounds write
A crafted hyperloglog value corrupts memory and can lead to remote code execution. Fixed in 6.2.19 / 7.2.10 / 7.4.5 / 8.0.3.
Our CVE page →
CVE-2026-23631 · conditional
Lua UAF via replica sync
Affects only replicas running with replica-read-only disabled — a setting the audit reads and reports, so the finding says whether the precondition is actually met on your instance.
Our CVE page →
July 2026 · no CVE id yet
Streams shared-NACK use-after-free
Seven security releases on 23 July 2026, after public proof-of-concept chains landed against stock 6.2.22 / 7.4.9 / 8.6.4 / 8.8.0. No CVE was assigned, so it has no page — but NewScan still reports it, because a version being unpatched does not depend on an identifier existing. Fixed in 6.2.23 / 7.2.15 / 7.4.10 / 8.2.8 / 8.4.5 / 8.6.5 / 8.8.1.
Every Redis advisory NewScan matches
The full set, server and modules. Each row is matched against the version read from the instance itself, so nothing here fires on a guess — and each links to our page for that CVE.
| CVE | Product | What it is | Fixed in | Severity |
|---|---|---|---|---|
| CVE-2025-49844 | Redis | "RediShell" — Lua use-after-free from a crafted EVAL script → RCE | 7.2.11 / 7.4.6 / 8.0.4 / 8.2.2 | critical |
| CVE-2026-23479 | Redis | Use-after-free in the unblock-client flow → RCE | 6.2.22 / 7.2.14 / 7.4.9 / 8.2.6 / 8.4.3 / 8.6.3 | high |
| CVE-2026-25243 | Redis | Invalid memory access in RESTORE from a crafted serialized payload → RCE | 6.2.22 / 7.2.14 / 7.4.9 / 8.2.6 / 8.4.3 / 8.6.3 | high |
| CVE-2026-23631 | Redis | Lua use-after-free via master–replica sync → RCE. Only when replica-read-only is off — which the audit reads | 6.2.22 / 7.2.14 / 7.4.9 / 8.2.6 / 8.4.3 / 8.6.3 | medium |
| CVE-2025-32023 | Redis | Hyperloglog out-of-bounds write → RCE | 6.2.19 / 7.2.10 / 7.4.5 / 8.0.3 | high |
| CVE-2024-46981 | Redis | Lua use-after-free via garbage-collector manipulation → RCE | 6.2.17 / 7.2.7 / 7.4.2 | high |
| CVE-2024-31449 | Redis | Lua library stack overflow via a crafted EVAL script → RCE as the Redis process | 7.2.5 | high |
| July 2026 (no id) | Redis | Streams shared-NACK use-after-free + RedisBloom/TDigest out-of-bounds writes → RCE. No CVE was assigned, so it has no page — it is still detected | 6.2.23 / 7.2.15 / 7.4.10 / 8.2.8 / 8.4.5 / 8.6.5 / 8.8.1 | high |
| end-of-life | Redis | Branches before 6.2 get no security fixes at all — and predate both ACLs and TLS, so the hardening the findings above recommend isn't fully available | 6.2.x or later | high |
| CVE-2024-51737 | RediSearch | Integer overflow via a crafted FT.SEARCH/FT.AGGREGATE LIMIT or KNN argument → heap overflow, RCE | 2.6.24 / 2.8.21 / 2.10.10 | high |
| CVE-2026-25588 | RedisTimeSeries | Invalid memory access in RESTORE with the module loaded → RCE | 1.8.23 / 1.10.24 / 1.12.14 | high |
| CVE-2024-51480 | RedisTimeSeries | Integer overflow via crafted TS.* arguments → heap overflow, RCE | 1.8.16 / 1.10.16 / 1.12.5 | high |
| CVE-2026-25589 | RedisBloom | Invalid memory access in RESTORE with the module loaded → RCE | 2.4.23 / 2.6.28 / 2.8.20 | high |
| CVE-2024-55656 | RedisBloom | Integer overflow via CMS.INITBYDIM with large WIDTH/DEPTH → heap overflow, RCE | 2.4.13 / 2.6.16 / 2.8.5 | high |
Affected ranges come from the vendor advisories, one row per maintained branch, so a patched older branch is not flagged; confirm against the advisory before acting on a version match. Module CVEs track the module's version, not the server's.
How it's recorded
// audit-ready evidenceCATEGORY
Unauthenticated access maps to CWE-306 (missing authentication); the command and transport findings to CWE-16 (security misconfiguration).
SEVERITY
One calibrated severity that translates into each framework's risk rating and remediation SLA — no inflated numbers.
EVIDENCE
The endpoint, how it was discovered, and the exact values the server returned — including a note that the dangerous commands were checked, not executed.
Find out what your app says about its cache.
NewScan is free and self-hosted — bring your own key. Everything on this page runs in the deterministic floor, with no model and no provider key at all.