Skip to content

Security: ethanschweiger/redis-clone-cpp

Security

docs/SECURITY.md

Security and Correctness

This project has received two focused review passes, not a comprehensive security audit. One pass searched for client-controlled inputs that could crash the server. A second reviewed authentication, resource limits, persistence durability, and background persistence behavior.

It remains a learning project and should not be exposed to an untrusted network.

Remotely triggerable crashes fixed

  1. KEYS and PSUBSCRIBE patterns containing many * characters could overflow the process stack because glob matching recursed once per wildcard. The matcher is now iterative, and the pathological pattern is covered by a live-server regression test.
  2. CONFIG SET with a non-numeric value for numeric settings such as port, databases, or maxmemory could throw an uncaught std::invalid_argument and terminate the process. Numeric parsing is now non-throwing and returns a normal client error. This also has a live-server regression test.

As defense in depth, Server::dispatch() catches exceptions escaping command handlers and converts them to per-client error replies.

Access control and resource limits

  • requirepass and AUTH provide a single shared secret. When configured, an unauthenticated connection is gated until authentication succeeds. This is not a multi-user permission system.
  • maxclients defaults to 10,000. Connections beyond the limit receive an explicit error and are closed.
  • maxclientinputbufferbytes defaults to 1 GiB and bounds unprocessed input.
  • maxclientoutputbufferbytes defaults to 64 MiB and bounds buffered replies, including data queued for a Pub/Sub subscriber that stops reading.

Persistence durability

  • AOF writes honor appendfsync always|everysec|no; the default is everysec.
  • RDB-style snapshots attempt best-effort fsyncs of the temporary file before rename and the containing directory afterward.
  • BGSAVE and BGREWRITEAOF fork child processes so serialization does not block the event loop. Writes received during an AOF rewrite are buffered and, after the child file is renamed, appended to the reopened AOF when the rewrite completes normally.
  • AOF rewrites preserve TTLs. Regression tests restart a real server and verify both the TTL and a write issued during the rewrite window survive.
  • Snapshot loading caps file-controlled string lengths and collection counts before allocating memory.

Remaining risks

  • There is no TLS. Traffic is plaintext, including the AUTH password.
  • Authentication uses one shared password; there are no multi-user ACLs, per-command permissions, or key restrictions.
  • There is no rate limiting.
  • Networking is IPv4-only.
  • Expensive commands can occupy the single event-loop thread. Large keyspace scans or glob matching can therefore delay every connected client even when buffer limits prevent unbounded memory growth.
  • AOF rewrite-window writes exist only in memory until after the rewritten file is renamed and reopened. A process or host crash during that window can lose acknowledged writes; the implementation does not yet provide Redis-grade rewrite durability.
  • Snapshot fsync failures and AOF write()/fsync() failures are not surfaced to clients. Storage errors can therefore go unreported.
  • The custom RDB-style format is not wire-compatible with Redis RDB and has not been hardened to the standard expected of a production database format.

There aren't any published security advisories