# 2026-05-30 — 安全加固：Health 纯文本 + sha256 替换 + 未登录页面空白 HTML

## 背景
1. `/health` 端点返回 `{"status":"ok"}` JSON，curl 看到 FastAPI JSON 指纹
2. bandit 扫描 sync_v2.py 命中 `hashlib.md5()` → CWE-327 HIGH
3. 未登录用户访问 `/app/` 页面，HTML 内容完整返回，虽前端无数据但暴露系统存在

## 变更内容

### 1. Health 端点纯文本（`server/api/health.py`）
- `@router.get("/health", response_class=PlainTextResponse)` 返回纯文本 `"ok"`
- 移除 `{"status":"ok"}` JSON 格式，curl 只看到 `ok`
- `/health/detail` 仍为 JSON，但需要 JWT 认证

### 2. 文件校验 sha256（`server/api/sync_v2.py`）
- `hashlib.md5()` → `hashlib.sha256()`
- 远程 SSH 命令 `md5sum` → `sha256sum`
- 消除 bandit CWE-327（弱哈希算法）

### 3. AppAuth 中间件（`server/main.py` + `server/api/auth_jwt.py`）
- 新增 `AppAuthMiddleware`：纯 ASGI 中间件，拦截 `/app/` 路径
- 读取 `nexus_refresh` HttpOnly cookie，验证 JWT
- 无有效 token → 返回空白 HTML 404（不暴露系统存在）
- 白名单：`/app/login.html`、`/app/install.html`、`/app/vendor/` 仍可访问

## 涉及文件
- `server/api/health.py` — 67 行（8 行改动）
- `server/api/sync_v2.py` — 1045 行（10 行改动）
- `server/main.py` — 472 行（新增 AppAuthMiddleware）
- `server/api/auth_jwt.py` — 272 行（提取 _verify_token_from_cookie）
- `docs/audit/2026-05-30-deploy-health-fix.md` — 审计记录

## 验证
- `curl https://api.synaglobal.vip/health` → `ok`（纯文本）
- `bandit -r server/ -ll` → 0 HIGH
- 未登录 curl `/app/index.html` → `404` 空白 HTML
- 已登录浏览器 → 页面正常
