Database audit fix

How to Configure Redis Authentication and Bindings

Redis accepts every connection by default: with no requirepass and no ACL, anyone who reaches the port can read your data, run FLUSHALL, or write files through CONFIG SET. Set a long requirepass, or Redis 6+ ACL users.

Hiren KalariyaLast reviewed: Aug 30, 2026Check redis-authentication
High
severity
Yes
needs root or sudo
6
results it can return
8 of 8
checks in this audit

Every threshold on this page is transcribed from the database-security-authentication audit script that CtrlOps runs, and a build check fails if the two ever disagree. See all 8 Authentication checks, or how the audit runs.

High severityNeeds sudo

What this check reads

In redis.conf (whichever of /etc/redis/redis.conf or /etc/redis.conf exists) it looks for an uncommented requirepass <value> (HASPW) or any user ... / aclfile ... line (HASACL). Either one on its own is the PASS: the check does not judge the strength of the password or the scope of the ACL. It also reads the last bind line; if any address is not loopback (127.0.0.1, ::1, -::1, localhost) it sets EXTB=1, which is what turns the no-credential case from a WARN into a FAIL.

When it applies

Runs only when Redis is detected (HAS_RD=1: a redis-server binary, a running redis-server, or a config at /etc/redis/redis.conf / /etc/redis.conf). It needs one of those two config paths (RDCONF) - anywhere else gives WARN - and root/sudo to read it, otherwise SKIP. This is a config-file check: a password set at runtime with CONFIG SET requirepass and never persisted with CONFIG REWRITE is not seen, and an included file is not followed. Whether the FAIL or the softer WARN branch fires depends on the last bind line: any non-loopback address makes it FAIL.

What each result means

Result thresholds this check applies
ResultWhenWhat it means
SKIPRedis not installedNothing was checked. No redis-server binary, process or config file was found.
WARN`redis.conf` not found at the two standard pathsRedis is present but its config was never read, so the credential is unconfirmed rather than known to be missing.
PASS`requirepass` or ACL configuredRedis asks callers for a credential. How strong or how scoped it is falls outside this check.
FAILNo auth and bound beyond loopbackAnyone who can reach the port has full access, including writing files to disk through CONFIG SET.
WARNNo auth, loopback onlyNo remote attacker can reach it directly, but any local process or an SSRF bug in your application can. Set requirepass anyway.
SKIPRoot needed to read the configNothing was read. The config file is there but was unreadable, so no conclusion is drawn.

Why it matters

Redis has no authentication by default. An unauthenticated Redis reachable from the network allows data theft, FLUSHALL, and historically remote code execution via CONFIG SET dir/dbfilename to write SSH keys or cron files, and via the MODULE LOAD primitive. Redis docs: "Redis is designed to be accessed by trusted clients inside trusted environments". Even loopback-only Redis is reachable by any local process and by SSRF from a web app. Redis 6+ recommends ACL users over the single requirepass.

Why it fails, and when it is wrong

  • Runtime CONFIG SET requirepass without CONFIG REWRITE is invisible to this file-based check. Use redis-cli CONFIG GET requirepass to see the live value.
  • Config at a non-standard path (Docker, Snap, /etc/redis/6379.conf) gives WARN "not found".
  • A password set via an included file (include /etc/redis/auth.conf) is not seen.
  • bind 0.0.0.0 with protected-mode yes and no password: Redis still refuses non-loopback clients, but the script treats it as FAIL because protected mode is a fallback, not a control.
  • The bind default in recent redis.conf is bind 127.0.0.1 -::1; when the directive is absent Redis binds all interfaces but protected-mode applies.

How to fix it

# /etc/redis/redis.conf
bind 127.0.0.1 -::1
protected-mode yes
requirepass <64 random chars>
# Redis 6+ preferred: ACL users with least privilege
user app on >strong-password ~app:* +@read +@write -@dangerous
user default off
rename-command CONFIG ""      # optional, or restrict via ACL

Then systemctl restart redis-server and update clients (AUTH / --pass).

Verify the fix

# The live value is authoritative:
redis-cli CONFIG GET requirepass        # expected: a long value, not empty
redis-cli ACL LIST                      # Redis 6+: expected least-privilege users, "user default off"

# An unauthenticated command must now be refused:
redis-cli PING
# expected: (error) NOAUTH Authentication required.

redis-cli -a "$REDIS_PASSWORD" --no-auth-warning PING     # expected: PONG

Debugging

Confirm with command -v redis-server; pgrep -a redis-server.

sudo grep -nE '^(requirepass|bind|user |aclfile)' /etc/redis/redis.conf.

The config lives somewhere the check does not look (Docker, Snap, /etc/redis/6379.conf). Locate it with ps -o args= -C redis-server; the first argument after the binary is the config path. The check reads only the two standard paths.

You set it at runtime. redis-cli CONFIG GET requirepass shows the live value; persist it with redis-cli CONFIG REWRITE (or write it into the config file) so it survives a restart and is visible to the check.

Deliberate. Protected mode is a fallback that disappears the moment any password or bind is configured; the check wants an explicit credential. Set requirepass or ACLs.

The script uses the last bind line only: sudo grep -E '^bind[[:space:]]' "$RDCONF" | tail -1. Anything other than 127.0.0.1, ::1, -::1 or localhost in that line sets EXTB=1 and turns the WARN into a FAIL.

Sources

How the script reads this

Next

Re-run the Authentication audit after applying the fix and confirm this check moves to PASS. CtrlOps runs all 8 checks over your existing SSH connection and scores the result, so the change is visible without reading another config file.

All 8 Authentication fixes
Audit your fleet

Find every one of these on every server, in one click

CtrlOps runs this audit over your existing SSH connection - no agents, no scripts to manage. $7/user/month after a 1 month free trial - no credit card required.

✓ Start instantly·✓ No credit card·✓ No sneaky autorenewals