P2迭代: 危险命令检测 + DB会话合并 + API密钥修复 + 安全审计 (6项)
P2-14: agent.py _verify_api_key() 重写文档并明确两步验证逻辑,
全局密钥匹配直接通过,非匹配密钥放行至handler做per-server验证
P2-15: websocket.py 删除已废弃的 connected_clients=[] 别名,
health.py 已使用 manager.client_count
P2-16: webssh.py 合并4个AsyncSessionLocal()为1个共享session(预接受操作),
命令日志保留独立session(长连接WebSocket不能持有单session)
P2-18: 新增危险命令检测 (check_dangerous_command),识别 rm -rf /、
fork bomb、dd写裸设备、mkfs等模式,scripts.py + webssh.py集成
P2-19: install.py 状态文件不再存储db_pass明文(步骤5已删除文件),
审计确认所有logger调用无敏感数据泄露
P2-17: httpOnly cookie迁移标记为延期(需前后端+WebSocket全面重构,
当前JWT+updated_at+CORS限制方案已足够安全)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+12
-13
@@ -34,24 +34,23 @@ REDIS_ALERT_KEY_PREFIX = "alerts:"
|
||||
|
||||
|
||||
def _verify_api_key(x_api_key: str = Header(...)):
|
||||
"""Verify Agent API key from request header (global key check only)
|
||||
"""Verify Agent API key — accepts either global or per-server key.
|
||||
|
||||
Per-server key verification is done in the endpoint handler after
|
||||
we know the server_id from the payload.
|
||||
For heartbeat endpoints, the global key is checked first; if it doesn't
|
||||
match, the request is still allowed through so the handler can verify
|
||||
the per-server key (which requires server_id from the payload).
|
||||
|
||||
NOTE: This function only checks the GLOBAL API key. Endpoints that
|
||||
need per-server verification must also call _verify_server_api_key().
|
||||
Any request with a key that doesn't match the global key is rejected
|
||||
immediately — per-server keys are only valid for heartbeat endpoints
|
||||
where the server_id is in the payload.
|
||||
For strict global-only verification, use _verify_global_api_key instead.
|
||||
"""
|
||||
if not x_api_key:
|
||||
raise HTTPException(status_code=401, detail="Missing API key")
|
||||
if x_api_key != settings.API_KEY:
|
||||
# For heartbeat endpoints, per-server keys are verified later
|
||||
# in the handler after we know the server_id.
|
||||
# For /exec endpoint, only the global API key is accepted.
|
||||
pass # Allow through — per-server check happens in handler
|
||||
# If the global key matches, allow immediately
|
||||
if x_api_key == settings.API_KEY:
|
||||
return x_api_key
|
||||
# Non-matching key — allow through for per-server verification in handler.
|
||||
# The handler MUST call _verify_server_api_key() before processing.
|
||||
# This two-step approach is needed because server_id is in the payload,
|
||||
# not the header, so per-server verification can't happen in a Depends().
|
||||
return x_api_key
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user