As33
@periodic/
arsenic
redis_flushall
🔴 Critical

Deletes every key in every database on the Redis instance — no confirmation, no undo

FLUSHALL wipes all keys across all Redis databases in a single command. There is no partial execution, no dry-run, and no recovery path. In production this is almost always a catastrophic mistake — wiping cache causes a thundering herd, wiping sessions logs out every user, and wiping queue data loses every pending job.

Common Causes

  • Development commands accidentally run against a production Redis URL
  • Test teardown scripts using the wrong environment variable
  • Admin tooling without environment guards
  • Migration scripts that lack confirmation prompts before destructive steps

How to Fix

  1. 1.Restrict FLUSHALL via Redis ACLs — remove it from the application user entirely
  2. 2.Use separate Redis instances per environment (dev, staging, prod)
  3. 3.Add environment guards in any script that runs destructive commands
  4. 4.Replace with targeted DEL or UNLINK on known key patterns

This cannot be undone

FLUSHALL fires immediately and irreversibly. If your application user can issue it, a single misrouted request or misconfigured script can wipe your entire cache, session store, and queue simultaneously.

Example

typescript
// BAD — wipes every key in every Redis DB
await redis.flushall();

// GOOD — targeted deletion with confirmation guard
async function clearCacheNamespace(redis: Redis, namespace: string) {
  if (process.env.NODE_ENV === 'production') {
    throw new Error('Namespace clear requires explicit production flag');
  }

  let cursor = '0';
  do {
    const [next, keys] = await redis.scan(cursor, 'MATCH', `${namespace}:*`, 'COUNT', 100);
    cursor = next;
    if (keys.length > 0) await redis.unlink(...keys);
  } while (cursor !== '0');
}

// GOOD — during test teardown, use isolated Redis DB
// config/test.ts
const testRedis = new Redis({ db: 15 }); // isolated DB index
afterAll(() => testRedis.flushdb()); // only clears DB 15

Locking down with ACLs

bash
# redis.conf — remove destructive commands from app user
ACL SETUSER appuser ~* +@all -flushall -flushdb -keys

# For test/admin users only — require explicit password
ACL SETUSER adminuser on >admin-secret +@all

Environment guard pattern

typescript
// lib/redis-admin.ts — wrap destructive ops with guards
export async function dangerFlushAll(redis: Redis, confirm: string) {
  if (confirm !== 'YES_I_KNOW_WHAT_I_AM_DOING') {
    throw new Error('Must pass explicit confirmation string');
  }
  if (process.env.NODE_ENV !== 'development') {
    throw new Error('FLUSHALL is only allowed in development');
  }
  await redis.flushall();
}