feat: T-03 输入防护限流(T3-3)——actor 级 Redis 固定窗口 30 次/分(settings 可调), 超限 429 GUARD_RATE_LIMITED+留痕, Redis 故障 fail-open, 测试 4 例(429/窗口滚动/fail-open/注入计数), 376 绿

This commit is contained in:
2026-09-07 11:10:26 +08:00
parent 65b45aa917
commit cc6f34fbbd
5 changed files with 172 additions and 6 deletions
+20
View File
@@ -106,6 +106,26 @@ def chat_api(req: ChatRequest, request: Request, auth: AuthContext = Depends(get
if not message:
raise ApiError(400, "BAD_REQUEST", "message is blank")
# T-03 限流(actor 级固定窗口,拍板 30 次/分):先于内容防护——计数
# 覆盖全部请求(含将被注入拦截的),重复攻击者快速收敛到 429,不再
# 逐条扫描+留痕;Redis 异常 fail-open(可用性保护非安全边界)。
if not input_guard.check_rate_limit(agent_type, auth.actor_id):
try:
_repo().insert_input_guard_log(
trace_id=current_trace() or new_trace(),
agent_type=agent_type,
actor_id=auth.actor_id,
guard_type=input_guard.GUARD_RATE_LIMIT,
action="blocked",
raw_excerpt=f"rate limited: {auth.actor_id}",
session_id=req.session_id,
)
except Exception:
logger.warning(
"rate limit log failed (degraded): actor=%s", auth.actor_id, exc_info=True
)
raise ApiError(429, "GUARD_RATE_LIMITED", "rate limit exceeded, retry later")
# T-03 输入防护(F-03/G-03):准入后、会话解析前 fail-fast——被拒输入
# 不建会话、不落消息表。命中即拒(拍板:宁可误拒不可漏放);留痕失败
# 降级 warning,拒绝语义优先(与 deps 401/403 留痕降级同口径)。