# Phase 1 Delta 审计 — Wave D3（服务器 / 设置 / 脚本 / WebSSH）

**日期**: 2026-06-04  
**范围**: Code Review batch2–3 相关路径  
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步

## 登记

| # | 文件 | 语言 | 行数 N | Read 范围 |
|---|------|------|--------|-----------|
| 1 | `server/api/webssh.py` | Python | 398 | 1–398 全文 |
| 2 | `server/api/servers.py` | Python | 1741 | 1–250, 1059–1290, 1681–1742 + 全路由 grep |
| 3 | `server/api/settings.py` | Python | 1403 | 1–130, 280–384, 562–730, 881–930 + grep |
| 4 | `server/application/services/script_service.py` | Python | 734 | 1–734 全文 |
| 5 | `server/api/scripts.py` | Python | 418 | 1–418 全文 |

## 入口表（摘要）

### webssh.py
| 类型 | 路径 | 鉴权 |
|------|------|------|
| WS | `/ws/terminal/{server_id}` | JWT `purpose=webssh` + server_id 绑定 |

### servers.py（主要写操作）
| 方法 | 路径 | 鉴权 |
|------|------|------|
| POST/PUT/DELETE | `/api/servers/`… | JWT |
| POST | `/{id}/agent-key` | JWT + 当前密码 |
| POST | `/{id}/install-agent` 等 | JWT + SSH |

### settings.py
| 方法 | 路径 | 鉴权 |
|------|------|------|
| GET/PUT | `/api/settings/*` | JWT；IMMUTABLE_KEYS 403 |
| POST | `/api-key/reveal`, `/telegram/reveal-token` | JWT + re-auth |

### scripts.py
| 方法 | 路径 | 鉴权 |
|------|------|------|
| CRUD/exec | `/api/scripts/*` | JWT 全路由 |

## Closure 表

| H | 文件:行号 | 判定 | 理由 |
|---|-----------|------|------|
| H-WS-auth | webssh.py:96-109 | SAFE | webssh JWT + server_id 必须匹配路径 |
| H-WS-IDOR | webssh.py:106-108 | SAFE | 非绑定 token → 4003 |
| H-WS-cred | webssh.py:127-135 | SAFE | SSH 凭据未配置则拒绝 |
| H-WS-audit | webssh.py:137-157 | SAFE | connect/disconnect 审计 |
| H-WS-cmdlog | webssh.py:276-290 | SAFE | 命令日志 + dangerous check |
| H-WS-ADR011 | webssh.py:92 | RISK | query token；已接受 |
| H-Server-mask | servers.py:1692-1698 | SAFE | password_set / 密钥不返回明文 |
| H-Server-encrypt | servers.py:1096-1099 | SAFE | Fernet 加密存储 |
| H-Server-allowlist | servers.py:1163-1187 | SAFE | UPDATE 字段白名单 |
| H-Server-agent-key | servers.py:1251-1288 | SAFE | re-auth 后生成/返回一次 |
| H-Server-shell | servers.py:631-633 | SAFE | install cmd shlex.quote |
| H-Server-sudo | servers.py:36-60 | RISK | 临时 sudoers；运维必要 |
| H-Settings-immutable | settings.py:331-334 | SAFE | api_key 等不可 PUT |
| H-Settings-mask | settings.py:114-128 | SAFE | GET 敏感项 value 空 + value_set |
| H-Settings-reauth | settings.py:93-98 | SAFE | reveal 需 bcrypt |
| H-Settings-SSRF | settings.py:68-88 | SAFE | 订阅 URL 私有 IP 拦截 |
| H-Settings-PUT-leak | settings.py:383 | RISK | PUT 响应可能含 telegram 明文；JWT 已认证 |
| H-Script-danger | scripts.py:352-359 | SAFE | check_dangerous_command 拒绝 |
| H-Script-cred | scripts.py:407-418 | SAFE | 凭据 API 无 password 字段 |
| H-Script-allowlist | scripts.py:111-114,303-306 | SAFE | credential/script UPDATE 白名单 |
| H-Svc-redact | script_service.py:108-111 | SAFE | 执行记录 command 脱敏 DB_PASS |
| H-Svc-ssh | script_service.py:680-698 | SAFE | SSH exec 经 pool |
| H-Svc-kill | script_service.py:306-322 | SAFE | kill 命令 pid/log 路径校验 |
| H-Svc-server-map | script_service.py:519-523 | SAFE | 预加载 server_map 避免并行竞态 |

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

## FINDING

无 P0/P1 新 FINDING。

## DoD

- [x] len(H) == Closure
- [x] Read 覆盖（大文件分段 + 全路由）
- [x] 逐行完成 ✓（D3 五文件）

## 验证

`bash scripts/local_verify.sh` — 预期全绿
