security: harden Redis ACL validation safety - #19
Merged
Merged
Conversation
On 2026-09-18, production Redis was accidentally FLUSHALL'd during ad hoc redis-exporter ACL negative testing: Redis's `default` user was enabled with nopass, so a connection was already authenticated as `default` the instant it opened; an explicit AUTH to a named identity with the wrong password failed but did not deauthenticate the connection, and subsequent commands -- including FLUSHALL -- executed with default's unrestricted permissions instead of failing. Adds scripts/redis_acl_safety.py, a small framework that makes this failure class structurally impossible for any caller that uses it: explicit, independently-reverified environment classification (DISPOSABLE requires a live nonce round-trip, never inferred from a hostname/port/empty-env-var; UNKNOWN is treated at least as strictly as PRODUCTION everywhere); every authenticated session is a brand-new connection that is closed unconditionally on any AUTH failure before a second command can reach the wire; identity is asserted via ACL WHOAMI before any validation command runs, with no warning-only fallback; a narrow production command allowlist plus a hard dangerous-command denylist (FLUSHALL, FLUSHDB, SHUTDOWN, DEBUG, CONFIG SET, ACL mutations, MIGRATE/RESTORE/SWAPDB/REPLICAOF/SLAVEOF, ...); and no public method that exposes the underlying redis-py client. tests/test_redis_acl_safety.py reproduces the actual incident sequence against a genuinely disposable Redis instance (started fresh via Docker for the test session, mirroring tests/_redis_integration_guard.py's existing no-implicit-default / no-production-port conventions), proves this framework survives it, and covers command-gate parsing (case, bytes, subcommand splitting), identity mismatch, authentication failure shapes, disposable-only destructive proof via DisposableNegativeTestGate, unknown-environment strictness, and the raw-client bypass surface. 86 tests, all passing; full existing suite unaffected (475 passed, 23 skipped, 0 failed). No production Redis was touched to build or test this. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
scripts/redis_acl_safety.py, a framework that structurally prevents the failure class behind the 2026-09-18 production Redis FLUSHALL incident: explicit, independently-reverified environment classification (DISPOSABLE/PRODUCTION/UNKNOWN), fresh-connection-per-identity with unconditional close on any AUTH failure, hard identity assertion viaACL WHOAMI, a narrow production command allowlist plus a dangerous-command denylist, and no public accessor for the underlying redis-py client.tests/test_redis_acl_safety.py, which reproduces the actual incident sequence (failed AUTH leaving a connection authenticated asdefault) against a genuinely disposable Redis instance, and covers command-gate parsing, identity mismatch, authentication-failure shapes, disposable-only destructive proof, unknown-environment strictness, and the raw-client bypass surface.Test plan
pytest -q tests/test_redis_acl_safety.py— 86 passed, 0 failed🤖 Generated with Claude Code