Vulnerability

Exposed Redis (Port 6379)
detect, harden, and verify closure

Internet-facing Redis on TCP 6379 with no AUTH, no ACL, the legacy protected-mode bypass, dangerous commands enabled, an outdated build, or a permissive cloud security group is one of the most consistently exploited cache and data-store exposure paths in cloud, container, and on-premise estates. Mass-exploitation campaigns (Meow, P2Pinfect, HeadCrab, Migo, Muhstik, Redigo) have wiped, mined, or backdoored hundreds of thousands of unauthenticated Redis instances across successive sweeps. Learn how to detect Redis exposure, lock it down, and keep the closure verifiable.

No credit card required. Free plan available forever.

Severity

Critical

CWE ID

CWE-306

OWASP Top 10

A05:2021 - Security Misconfiguration

CVSS 3.1 Score

9.8

What is exposed Redis?

Exposed Redis is the cluster of weaknesses that turn a Redis (or Valkey, KeyDB, or DragonflyDB) cache, queue, or session store into a direct data-breach, ransomware, and remote-code-execution path. The most common shape is an internet-facing listener on TCP 6379 with the legacy protected-mode bypass, no requirepass configured, no AUTH ACL applied, a permissive bind 0.0.0.0 setting, no TLS for client and replica traffic, the dangerous CONFIG, DEBUG, MODULE, SLAVEOF, REPLICAOF, EVAL, and FLUSHALL commands left enabled, an outdated build behind the upstream support window, or a cloud security group that opens 6379 to the public internet during a migration that nobody narrowed back down.

Internal-only Redis instances are not safe by definition either. Lateral movement from a compromised application host, supply-chain compromise of a deploy pipeline, a sidecar agent reaching the wrong namespace, a Sentinel or Cluster bus port left open on TCP 16379 or 26379, or a developer-built side instance that joins production by accident all read the same misconfigurations as a public attacker would. Sister exposures land on the same hosts: an internet-facing SSH listener is often what gives the attacker the foothold from which the open Redis instance gets enumerated, an exposed MongoDB instance or an exposed Elasticsearch index frequently shares a host with the open Redis listener, and an exposed Docker socket gives the same attacker root-equivalent control of the host that often runs the cache container.

The track record is unambiguous. The 2020 Meow attacks scripted indiscriminate deletion of exposed Redis instances alongside MongoDB, Elasticsearch, and Cassandra without leaving a ransom note. The P2Pinfect worm (2023 onward) industrialised unauthenticated Redis takeover at scale, propagating across cloud regions through the SLAVEOF / REPLICAOF replication path and using EVAL Lua sandbox escapes to drop a Rust-based botnet binary. The HeadCrab campaign (2023 onward) abused Redis MODULE LOAD against vulnerable builds to deploy a stealth in-memory kernel module loader that survived restarts. The Migo cryptojacking campaign (2024) chained protected-mode bypass with CONFIG SET dbfilename to write attacker keys into /root/.ssh/authorized_keys, then sustained access through systemd unit injection. Shodan and Censys index hundreds of thousands of Redis listeners on TCP 6379 at any moment. CISA and the FBI continue to flag exposed cache and database services among the leading initial-access and data-theft enablers.

Exposed Redis is also a recurring audit, cyber-insurance, and cloud-account isolation finding. PCI DSS Requirement 1.3, 2.2, 7.1, 8.3, and 10.2, ISO 27001 Annex A.5.15, A.8.5, A.8.20, A.8.21, A.8.24, and A.8.25, NIST SP 800-53 SC-7 (boundary protection), AC-3, AC-6, IA-2, and CM-7, the CIS Critical Security Controls v8.1 Control 3 (data protection), Control 4 (secure configuration), and Control 13 (network monitoring), GDPR Articles 32 to 34, HIPAA 45 CFR 164.312, and most cyber-insurance questionnaires either prohibit or restrict direct internet exposure of in-memory data stores and require documented hardening of those that remain. Closing the exposure or hardening the listener is almost always inexpensive compared to the operational, regulatory, and reputational cost of leaving it open, which is why this class of finding tends to move quickly through remediation tracking once it is surfaced on a controlled record.

How attackers exploit it

1

Discover open 6379

Attackers continuously scan IPv4 (Shodan, Censys, Masscan, ZMap, ZGrab, and custom Go and Python tooling) for hosts answering on TCP 6379 and the Sentinel and Cluster bus ports on 16379 and 26379. A single PING returns +PONG and reveals the listener; the INFO command (if reachable) advertises the Redis version, the build identifier, the operating system, the memory size, the configured persistence path, the number of databases, the connected client count, and the replication role before any credential is submitted, giving the attacker enough fingerprint to pick a CVE and a follow-on technique.

2

Probe authentication state

Tooling (redis-cli, redis-py, ioredis, custom Go clients, nmap redis-info script) checks whether the listener accepts commands without AUTH. Where requirepass is unset and protected-mode is off (or bypassed through the well-known 6379/0.0.0.0 default), the attacker runs CLIENT LIST, CONFIG GET *, INFO REPLICATION, KEYS *, and SCAN 0 directly. Where AUTH is on but weak, automated brute-force tooling replays leaked breach corpora against AUTH. Where AUTH ACL is on, the attacker tests default user permissions and probes for stale accounts left behind by quickstart configurations.

3

Exfiltrate, ransom, or wipe

Once authenticated or where no credential is required, attackers SCAN 0 COUNT 10000 across every database, MGET or HGETALL the high-value keys, copy the data to attacker storage, run FLUSHALL or DEL to wipe the instance, and leave a ransom note (a "README" or "BACKUP" key) demanding cryptocurrency for return. Meow-class attackers skip the ransom step and overwrite the keyspace with random data. Session stores leak active user sessions, cache stores leak credentials and tokens, queue backends leak unprocessed work.

4

Achieve code execution and persist

Attackers chain the open listener into code execution. The classic SSH-key path runs CONFIG SET dir /root/.ssh, CONFIG SET dbfilename authorized_keys, SET 0 "ssh-rsa attacker-key", and BGSAVE to write the attacker public key into the host. The replication path runs SLAVEOF attacker-controlled-host 6379 to pull a malicious RDB file and load it on disk. The module path runs MODULE LOAD /tmp/evil.so to load a shared object that opens a reverse shell. The Lua sandbox path runs EVAL with a payload that escapes the sandbox on unpatched builds. From there the attacker reads /etc/shadow, harvests cloud-metadata tokens, pivots to peer nodes, and stages cryptomining (P2Pinfect, Migo), data exfiltration, ransomware deployment, or persistent botnet recruitment.

Common causes

Cloud security group rule too broad

An AWS security group, Azure NSG, GCP firewall rule, or DigitalOcean firewall opens TCP 6379 to 0.0.0.0/0 during a Terraform run, a migration, a debug session, a vendor handoff, or a recovery exercise. The rule is never narrowed, and a public Redis listener persists across image rebuilds, autoscaling events, Sentinel failover, replica promotion, and account migrations. Managed offerings (ElastiCache, MemoryDB, Azure Cache for Redis, Memorystore) inherit the deployment defaults of whoever provisioned them, including peering routes that reach the wrong VPC.

requirepass and AUTH ACL unset

redis-server is started with no requirepass directive, no ACL user definitions, and protected-mode left at the legacy default that turns off when a non-loopback bind is configured. Docker quickstart images, Helm chart defaults, vendor appliances, and bare apt-get installs all ship without an authentication step. The first client connecting becomes a de facto admin. AUTH ACL was added in Redis 6 but is rarely configured beyond the default user, so leavers, rotated services, and rotated humans share the same credential.

bind set to 0.0.0.0 by default

Older Redis defaults bound to 0.0.0.0, and self-hosted deployments still inherit that pattern through legacy redis.conf files, Compose files, Helm chart values, vendor templates, and home-grown installs. Modern builds default to 127.0.0.1, but a single bind line in redis.conf or a single REDIS_PASSWORD-less environment variable in a Compose file restores the broad bind quickly. Sentinel and Cluster bus traffic on TCP 16379 and 26379 is frequently left open even when the data port is narrowed.

Outdated Redis build

Long-lived virtual machines, frozen container images, vendor-distributed appliances, and home-grown installs run a Redis release several years behind the upstream support window. End-of-life branches receive no security backports, and recent CVEs (including the Lua sandbox escape class, the LUA_SHIPPED expression evaluation flaws, the integer-overflow class in the HyperLogLog implementation, and the MODULE LOAD memory-corruption advisories) turn aged builds into immediate exposure events. Long-lived persistent storage means flushing the instance does not flush the version.

Dangerous commands left enabled

CONFIG, DEBUG, MODULE, SLAVEOF, REPLICAOF, EVAL, EVALSHA, FUNCTION, FLUSHALL, FLUSHDB, KEYS, BGSAVE, and BGREWRITEAOF remain available to any authenticated caller. Operators rarely use rename-command to disable or rename these in production, and the default user in AUTH ACL inherits +@all in the legacy quickstart. The CONFIG SET dir + dbfilename + SET + BGSAVE chain alone is sufficient for unauthenticated remote code execution on a host that runs Redis as a privileged user.

No TLS for client or replication traffic

Redis added TLS support in 6.0, but many deployments still serve plaintext on 6379 and replicate plaintext between primary and replica. Credentials, session tokens, application secrets, and customer data traverse the network in the clear. A passive observer on a shared VPC, a misrouted internal load balancer, a mirrored switch port, or a compromised hop reads the entire workload without ever needing to brute-force AUTH.

How to detect it

Automated detection

  • SecPortal's external scanner port-scan module probes TCP 6379 across every verified domain and host in scope, sends a PING probe to confirm the responding service is Redis, and raises a critical-severity finding under the rule that database and cache services should never be directly exposed to the internet. The Sentinel and Cluster bus ports on 16379 and 26379 are covered by the same sweep.
  • Continuous monitoring re-runs the external scan on a schedule, so a security-group edit, a Terraform apply, a Sentinel failover, an autoscale event, a managed-cache public-endpoint flag, or a recovered backup host that re-exposes 6379 reopens the finding rather than leaving the regression invisible until the next audit cycle.
  • Bulk import accepts Nessus, Burp, and CSV output from network-tier scanners and from Shodan and Censys exports that already list exposed Redis listeners, so the catalogue stays centralised even when a third-party tool is the original discovery source.

Manual verification

  • Use nmap -p 6379,16379,26379 with service detection (-sV) and the redis-info script against the external range to confirm the listener, the engine version, the role (master or replica), and whether AUTH is required.
  • Run redis-cli -h target -p 6379 PING against each reachable listener. A +PONG without an AUTH challenge is the definitive signal of an unauthenticated listener. Follow with INFO server, INFO replication, CLIENT LIST, and CONFIG GET dir to read the build identifier, the replication topology, and the persistence path.
  • Cross-reference the Redis build banner against the Redis release notes, the Redis security advisory page, and the CISA Known Exploited Vulnerabilities catalogue to identify whether any unpatched Redis CVE is present, including the Lua sandbox escape class and the MODULE LOAD memory-corruption advisories.
  • Check Shodan and Censys for the organisation's netblocks and known hostnames to see whether external observatories already list exposed Redis instances and the banners they advertise, then reconcile that list against the verified-domain inventory inside the workspace.

How to fix it

Remove direct internet exposure

Block TCP 6379 (and the Sentinel and Cluster bus ports on 16379 and 26379) inbound at the perimeter firewall, the cloud security group, and the load balancer for every host. There is no production scenario where a long-lived Redis listener should be reachable from 0.0.0.0/0. Reach the cache through a private subnet, a VPC peering or PrivateLink endpoint, a managed bastion service, or a zero-trust access broker. Managed cache services (ElastiCache, MemoryDB, Azure Cache for Redis, Memorystore) should be bound to private subnets with VPC endpoints rather than public access flags.

Enable AUTH and AUTH ACL

Set a long, random requirepass in redis.conf (or rotate the equivalent setting in the managed-cache console). For Redis 6 and later, define ACL users with command and key-pattern restrictions, set the default user to off or disallow all dangerous commands, and bind every application and operator account to the smallest ACL category bundle that lets it do its job. Confirm that redis-cli without AUTH returns NOAUTH Authentication required before declaring the change complete.

Lock the bind interface and protected-mode

Set bind to the specific private interface Redis should answer on, never 0.0.0.0. Keep protected-mode on. For Sentinel and Cluster, list each peer interface explicitly and restrict the bus ports to the same private boundary. Pair the bind with a private VPC and a security group that allows only the application tier, the replica peers, and the backup runner to reach 6379.

Patch the Redis build

Apply Redis Server updates promptly, especially advisories naming the Lua sandbox escape class, the LUA_SHIPPED expression evaluation flaws, the integer-overflow class in HyperLogLog and other modules, and the MODULE LOAD memory-corruption advisories. Move off end-of-life branches (pre-6.x, and any branch past upstream support) onto a supported version before the upstream support window closes. Treat Valkey, KeyDB, and DragonflyDB forks as their own patch streams with their own advisory feeds.

Disable or rename dangerous commands

Use rename-command in redis.conf to disable or rename CONFIG, DEBUG, MODULE, SLAVEOF, REPLICAOF, EVAL, EVALSHA, FUNCTION, FLUSHALL, FLUSHDB, KEYS, BGSAVE, and BGREWRITEAOF for every account that does not need them. Where AUTH ACL is in use, remove +@all from the default user and grant only the specific categories the application requires (+@read, +@write, +@stream, +@list, +@hash, +@set, +@sortedset). Block MODULE LOAD outright unless a vetted module is required.

Enable TLS encryption in transit

Set tls-port to 6379 (or run TLS on a separate port and shut the plaintext port), provide a certificate signed by an internal certificate authority, and enforce tls-auth-clients yes. Pair the TLS configuration with tls-protocols TLSv1.2 TLSv1.3 and a modern cipher list. Apply the same TLS expectations to replication traffic (tls-replication yes) so primary-to-replica traffic is encrypted. Audit driver versions to confirm every application client supports the modern cipher suite.

Run Redis as an unprivileged user

Start redis-server under a dedicated unprivileged system account, never as root. Refuse to chmod or chown the persistence directory into a location any non-Redis user can write. The CONFIG SET dir + dbfilename + SET + BGSAVE chain that writes an SSH key into /root/.ssh/authorized_keys depends on the process running as root; an unprivileged Redis cannot write that path, even if the AUTH gate is bypassed.

Enable audit logging and monitoring

Turn on Redis ACL logging (ACL LOG) for failed authentication and command-permission violations, forward the audit stream to the detection pipeline, and pair the listener with a brute-force detection rule for repeated NOAUTH failures. Track MONITOR usage carefully (it is itself a sensitive command). Watch the Redis slowlog for unexpected MODULE LOAD, SLAVEOF, CONFIG SET dir, and DEBUG attempts. Feed the same data into the workspace finding record so a hardening regression triggers a new finding rather than a silent revert.

Operationalising the fix on the workspace

Closing an exposed Redis instance and hardening redis-server is rarely the hard part for an experienced platform or cache engineer. The operational hard part is keeping the closure intact across rebuilds, autoscaling, Sentinel failover, replica promotion, vendor migrations, mergers and acquisitions, and the long tail of cloud accounts and on-premise hosts that nobody currently lists in a primary asset inventory. The workspace pattern below is what AppSec, cloud security, vulnerability management, data security, and security engineering teams use to keep an exposed-Redis finding from coming back six months later under a new account or a renamed host.

Surface every Redis listener on one finding record

External scanning and bulk import land every exposed-Redis detection on the findings management record with CVSS, the discovered host, the captured PING response, the build identifier, the replication role, the scan timestamp, and the named owner so the catalogue is a single source of truth rather than a Shodan tab, a spreadsheet, and a Slack thread.

Inspect configuration drift through authenticated scans

Where the team has authorisation, the authenticated scanning path reads the responding service in more detail and pairs the result with the per-host hardening record. Credentials for authenticated runs live in encrypted credential storage scoped to a verified domain so the same Redis AUTH secret is not copied across spreadsheets, chat threads, and pull-request bodies.

Run remediation as a tracked workflow

Each finding flows through the remediation tracking workflow with severity, target close date, named owner, and the agreed compensating control (for example, an inbound source allowlist while the PrivateLink endpoint is provisioned, or a temporary firewall rule while AUTH ACL is stood up). Permanent exceptions enter the eight-field exception register with a named approver, a rationale, an effective period, and a renewal cadence.

Verify the fix with retest

Once the firewall rule, security-group edit, redis.conf change, host retirement, or migration to a managed-cache private endpoint completes, the retesting workflow re-runs the external scan, confirms the listener is gone or that the responding service now requires AUTH on a private interface, and stamps the closure with timestamped evidence rather than a verbal sign-off in a stand-up.

Catch regressions through continuous monitoring

Scheduled continuous monitoring re-scans of verified domains reopen the finding if Redis returns to the public internet, if the banner drops back to an end-of-life build, or if a new cloud account joins the estate with an open 6379. A Terraform apply, a Sentinel failover, an autoscaler refresh, or a recovered backup image does not silently reintroduce the exposure.

Pair with the broader exposure catalogue

Exposed Redis rarely shows up alone. The same host frequently exposes SSH misconfiguration, default credentials, cloud bucket misconfiguration, or sensitive data exposure. Treating Redis exposure as one finding inside a host-level posture review keeps the queue ordered against real residual risk rather than chasing isolated ports one at a time.

Carry the audit trail through closure

The activity log records who opened, scoped, remediated, and verified each exposed-Redis finding, so the next ISO 27001, SOC 2, PCI DSS, HIPAA, or cyber-insurance review reads the operating evidence from the record rather than from reconstructed memory, archived ticket exports, or screenshots taken weeks after the fact. The same record drives compliance tracking across the framework crosswalk.

Communicate posture in leadership language

When cache exposure sits inside a broader programme review, the Claude-drafted AI report composes a leadership-ready narrative from the open and closed findings, the remediation cadence, and the linked compliance evidence. The same record drives security leadership reporting without rebuilding the slide deck by hand each quarter.

Where the exposure usually lands

Exposed Redis is not a single shape across the enterprise estate. The conversation a cloud security team has with a platform team about a self-hosted cache in a development VPC differs from the conversation a data security team has with an application team about an ElastiCache cluster reachable from the wrong peering route. The four contexts below are the most common landing places, and each one needs a slightly different remediation playbook surfaced on the same finding record.

Self-hosted Redis on cloud VMs

EC2, Compute Engine, Azure VM, and DigitalOcean droplet deployments of community-edition Redis make up the bulk of historic exposure events. Replace standing 0.0.0.0/0 security-group rules with private subnets, security-group source restrictions to application tiers, and managed bastion access for human operators. Move long-lived production workloads onto ElastiCache, MemoryDB, Azure Cache for Redis, or Memorystore where the network boundary is built in. Disable MODULE LOAD on every self-hosted instance unless a vetted module is required.

Managed Redis with permissive access

ElastiCache, MemoryDB, Azure Cache for Redis, Memorystore, Redis Enterprise Cloud, and Upstash all inherit the deployment defaults of whoever provisioned them. A public-access flag, a project-wide read role granted by accident, an unrotated programmatic API key, or a peering route that reaches the wrong VPC creates the same exposure pattern as a self-hosted listener. Bind every cluster to PrivateLink or VPC peering, enforce AUTH ACL with per-service ACL users, rotate access tokens quarterly, and use the managed service audit log as the source of truth for who connected when.

Containerised Redis in dev, test, and CI

Dockerised Redis instances inherit the official image defaults, environment-variable initialisation, and quickstart Compose files. A misrouted bridge network, a kubectl port-forward left running, an exposed service of type LoadBalancer, or an ingress-controller rule that catches more traffic than intended reopens 6379 quickly. Bake requirepass and AUTH ACL into the Helm chart, default to bind 127.0.0.1 in dev compositions, set protected-mode yes, and treat any LoadBalancer service for a cache as a finding to triage.

Legacy Redis on aged builds

Long-lived virtual machines, vendor-distributed appliances, customer-managed instances at acquired companies, and home-grown installs run a Redis release several years behind the upstream support window. End-of-life branches receive no security backports. Track these hosts on the finding record with the build identifier, the maintainer contact, and the upgrade path. Where the host cannot be upgraded immediately, isolate it behind a managed network access boundary, disable MODULE LOAD and the Lua-related commands outright, and document the residual risk decision in the exception register.

Compliance impact

Where Redis posture lands inside the team

Exposed Redis sits across several teams at once. The internal security team owns the policy, the audit response, and the breach-notification posture. The cloud security team owns the cloud-account perimeter, the security-group baseline, and the PrivateLink architecture. The data security team owns the encryption controls, the ACL bundles, and the audit-log review. The vulnerability management team owns the backlog, the prioritisation, and the SLA. The security engineering team owns the hardening tooling and the identity federation path. SecPortal keeps the same finding visible to all of them on the workspace record so the handoffs do not lose context as the work moves between owners.

Find every exposed Redis instance across your estate before someone else does

SecPortal's external scanner probes TCP 6379 across verified domains, confirms the responding service is Redis through a PING probe, raises a critical-severity finding with port and service evidence, tracks remediation through closure, verifies the fix through retest, and re-runs continuously so a security-group edit, a Terraform apply, a Sentinel failover, or a recovered backup image does not silently re-expose the cache. Start free.

No credit card required. Free plan available forever.