# Phase 2 深审 — Wave P2-4（servers.py 全文）

**日期**: 2026-06-04  
**范围**: 服务器 CRUD/Agent/导入/批量 SSH 全文 + 凭据加密/文件能力探测  
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步

## 登记

| # | 文件 | 语言 | 行数 N | Read 范围 |
|---|------|------|--------|-----------|
| 1 | `server/api/servers.py` | Python | 1742 | 1–1742 全文（分段 Read 至 EOF） |
| 2 | `server/infrastructure/database/crypto.py` | Python | 54 | 1–54 全文 |
| 3 | `server/infrastructure/ssh/files_capability.py` | Python | 63 | 1–63 全文 |
| 4 | `server/utils/files_elevation.py` | Python | 55 | 1–55 全文（P2-1 已读，本波交叉验证） |
| 5 | `server/infrastructure/ssh/remote_shell.py` | Python | 63 | 1–63 全文（P2-1 已读，setup-files-sudo 关联） |

## 入口表（servers.py 26 路由）

| 类别 | 路由数 | 鉴权 |
|------|--------|------|
| CRUD / 列表 / stats | GET/POST/PUT/DELETE | 全部 JWT |
| CSV import | POST `/import` | JWT + 1MB/500行 |
| 批量 Agent | POST `/batch/*` | JWT + Semaphore(5) |
| Agent 单台 | POST `/{id}/install|uninstall|upgrade-agent` | JWT |
| 敏感 reveal | POST `/{id}/agent-key`, `agent-install-cmd` | JWT + bcrypt re-auth |
| files | GET/POST `files-capability`, `setup-files-sudo` | JWT |
| health | POST `/check` | JWT |

## Closure 表

| H | 文件:行号 | 判定 | 理由 |
|---|-----------|------|------|
| H-Auth | servers.py:26×路由 | SAFE | 26 端点均 `get_current_admin` |
| H-Mask | servers.py:1692-1698 | SAFE | password_set / agent key 前缀截断 |
| H-Encrypt | servers.py:1096-1099,559-562 | SAFE | Fernet encrypt 入库 |
| H-Allowlist | servers.py:1163-1187 | SAFE | UPDATE 字段白名单；agent_api_key 排除 |
| H-Reauth | servers.py:1256-1260,1479-1483 | SAFE | agent-key/install-cmd 需当前密码 |
| H-Reveal | servers.py:1492-1502 | SAFE | install-cmd 不用全局 API_KEY |
| H-AgentKey | servers.py:1282-1288 | SAFE | 生成后 display_once 响应 |
| H-Fallback | servers.py:626,1321 | RISK | batch/single install 可回退 settings.API_KEY |
| H-Shell | servers.py:631-633,1330-1332 | SAFE | install shlex.quote url/key/port |
| H-Sudo | servers.py:36-60 | RISK | 临时 sudoers 白名单；运维必要 |
| H-SudoPwd | servers.py:1025-1027 | SAFE | sudo -S 密码走 stdin 非 argv |
| H-CSV | servers.py:376-388,445-446 | SAFE | formula injection 防御 + 1MB 上限 |
| H-CSV | servers.py:499-501 | SAFE | MAX_IMPORT_ROWS=500 |
| H-Batch | servers.py:615,686,772,850 | SAFE | Semaphore(5) 并发上限 |
| H-Redis | servers.py:179-201,873-877 | SAFE | 心跳 overlay；失败 log warning |
| H-Audit | servers.py: CUD/batch | SAFE | 写操作 AuditLog |
| H-Crypto | crypto.py:20-26 | SAFE | 无 ENCRYPTION_KEY 则 RuntimeError |
| H-Crypto | crypto.py:52-54 | SAFE | decrypt 失败 raise，非静默 |
| H-Capability | files_capability.py:31-39 | SAFE | 只读 probe，无密码回传 |
| H-Elevation | files_elevation.py:48-55 | SAFE | apply_files_elevation_payload |

**len(H)=20, Closure=20**

## FINDING

无 P0/P1 新 FINDING。

## DoD

- [x] servers.py 1742 行全文 Read（补 D3 分段）
- [x] len(H) == Closure
- [x] local_verify 通过

## 验证

`bash scripts/local_verify.sh` — 全绿
