Skip to content

[AI Review][P1] Redis 限流器存在永久锁定用户的风险 #253

@github-actions

Description

@github-actions

来源 PR:#251 #251

严重级别:P1
位置:apps/api/src/common/rate-limit/rate-limit.service.ts:64

风险

assertAllowedWithRedis 中,限流计数器使用 client.incr(key) 递增,并且仅在 count === 1 时调用 client.pExpire(key, input.windowMs) 设置过期时间。如果在高并发下或者在 incr 执行成功后、pExpire 执行前发生网络抖动、服务重启或 Redis 故障,该 Key 将永远不会被设置过期时间(TTL 为永久)。由于该 Key 不包含日期或时间戳,一旦丢失 TTL,该用户/IP 将被永久限制访问,除非手动删除 Redis Key。

建议

建议使用 Redis Lua 脚本原子性地执行 INCREXPIRE,或者无论 count 是否为 1,都确保设置过期时间。例如使用 Lua 脚本:

const lua = `
  local current = redis.call('incr', KEYS[1])
  if current == 1 then
    redis.call('pexpire', KEYS[1], ARGV[1])
  end
  return current
`;
const count = Number(await client.eval(lua, { keys: [key], arguments: [String(input.windowMs)] }));

Checked at: 2026-06-10T09:47:34.590366Z

Metadata

Metadata

Assignees

No one assigned

    Labels

    ai-reviewCreated by the AI review workflowneeds-triageNeeds human triage

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions