# API 巡检 B1 — servers.py + webssh.py **日期**: 2026-06-06 **范围**: `server/api/servers.py`(28 端点)、`server/api/webssh.py`(1 WS) **方法**: 8 维清单(认证/越权/注入/路径/凭据/输入/错误/审计) ## 结论 | 级别 | 数量 | 说明 | |------|------|------| | P0 | 0 | — | | P1 | 0 | — | | P2 | 1 | 已修:`ServerCheck.server_ids` 无上限 → DoS | | H | 3 | 已记录/接受,见下表 | **批次结论**: **PASS**(修复已合入工作区) --- ## 端点覆盖 全部 29 个路由均要求 `get_current_admin`(REST)或 WebSSH 专用 JWT(`purpose=webssh` + `server_id` 绑定)。 | 模块 | 端点 | 认证 | 审计 CUD | 备注 | |------|------|------|----------|------| | servers | CRUD `/` `/{id}` | JWT | ✓ | `_server_to_dict` 不返明文密码/私钥 | | servers | `/stats` `/categories` `/logs` | JWT | — | 只读;stats 有 online 封顶 | | servers | `/import` | JWT | ✓ | 1MB/500 行;CSV 注入防护 `_sanitize_csv_cell` | | servers | `/batch/*` | JWT | ✓ | `server_ids` max 50;SSH `shlex.quote` | | servers | `/add-by-ip` `/pending/*` | JWT | ✓(已补 retry 失败) | 轮询失败写 pending + 审计 | | servers | `/agent-key` `/agent-install-cmd` | JWT + 密码复核 | ✓ | 不回落全局 API_KEY | | servers | `/install-agent` | JWT | ✓ | 服务端 SSH 可用全局 KEY 作 fallback(H) | | servers | `/check` | JWT | — | **已修** max 50 server_ids | | webssh | `/ws/terminal/{id}` | JWT query | connect/disconnect | server_id 绑定;命令审计 + 危险命令检测 | --- ## FINDING 明细 ### P2-01 — `POST /api/servers/check` 无 `server_ids` 上限(已修) - **风险**: 传入数千 ID 触发并行 SSH 探测,资源耗尽。 - **修复**: `ServerCheck.server_ids` 增加 `max_length=50`(与 `BatchAgentAction` 一致)。 - **文件**: `server/api/schemas.py` ### H-01 — WebSSH 遗留 token 无 `tv` 字段时回退 `updated_at` 宽限 - **位置**: `webssh.py` `_verify_webssh_token` - **影响**: 改密后 5 秒内旧 WebSSH token 仍可能有效(新签发 token 均含 `tv`)。 - **处置**: 接受(单人运维模型);新 token 路径已安全。 ### H-02 — `install-agent` 无 per-server key 时回落 `settings.API_KEY` - **位置**: `servers.py` `install_agent_remote` - **影响**: 仅用于 SSH 下发安装命令,不向 API 响应暴露全局 KEY。 - **处置**: 接受;与 Agent 安装运维模型一致。 ### H-03 — `retry_pending` 失败与 `delete_pending` 审计字段不完整(已修) - **修复**: 失败重试写 `retry_pending_server_failed` 审计;删除前读取 pending 写入 `detail`。 - **文件**: `server/api/servers.py` --- ## 安全亮点(无需改动) - `_server_to_dict`: `password_set` / `ssh_key_private_set` / agent key 预览 - `update_server`: `ALLOWED_FIELDS` 白名单,禁止 mass-assign `agent_api_key` - `_sudo_wrap`: 临时 sudoers 白名单命令 + 事后清理 - `setup-files-sudo`: 密码经 stdin 喂 `sudo -S`,不进 argv - WebSSH: token `server_id` 与路径参数必须一致(防 IDOR) - CSV import: 大小/行数限制 + formula injection 防护 --- ## 验证 ```bash .venv/bin/pytest tests/test_credential_poller.py tests/test_security_unit.py -q ``` --- **下一批**: B2 — `sync_v2.py` + `files.py` + `remote_path_validation.py`