85 lines
3.3 KiB
Markdown
85 lines
3.3 KiB
Markdown
|
|
# 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`
|