3.3 KiB
3.3 KiB
Changelog — Settings 安全加固 + UX 迭代
日期: 2026-05-30
Commit: a50f179
类型: 安全修复 + UX 改进
涉及文件:
server/api/settings.py— SSRF 防护 + key 白名单 + 值校验 + IP 审计server/api/auth.py— 密码修改要求 TOTPserver/application/services/auth_service.py— _verify_totp staticmethodweb/app/settings.html— UX 全面改进 + 密码修改重定向web/app/login.html— 密码修改后提示
安全修复 (5 项)
S-01 SSRF 防护 (P0)
POST /api/settings/ip-allowlist/parse-subscription 可被利用探测内网。
- 新增
_is_private_host()函数:IP 直检 + DNS 解析后二次校验 - 封禁:loopback/link-local/private/reserved IP 段
follow_redirects=False,手动跟随最多 3 次重定向,每次检查目标- 响应大小限制 1MB
S-02 设置值校验 (P0)
PUT /api/settings/{key} 接受任意值。
- 新增
MUTABLE_KEYS白名单(27 个已知 key),未知 key → 403 - 新增
SETTING_VALIDATORS:6 个 INT 设置项的类型+范围校验- db_pool_size/db_max_overflow: 1-1000
- heartbeat_timeout: 10-600
- cpu/mem/disk_alert_threshold: 1-100
- 非整数值 → 400 "必须是整数",范围越界 → 400 "范围: X-Y"
S-05 改密码后重登录 (P1)
密码修改成功后前端仅清空表单,用户留在 stale JWT 页面。
- 成功后跳转
/app/login.html?msg=password_changed - login.html 显示绿色提示 "密码已修改,请重新登录"
S-07 IP 操作审计 (P1)
add_manual_ips 和 remove_allowlist_ip 缺少审计日志。
- 两个端点添加
request: Request参数 - 添加标准 AuditLog 写入(action/detail/ip_address)
S-09 改密码要求 TOTP (P1)
已启用 TOTP 的管理员改密码只需密码,可绕过 TOTP 保护。
ChangePasswordRequest新增totp_code: Optional[str]change_passwordhandler 检查:TOTP 已启用 + 未提供 code → 400AuthService._verify_totp改为@staticmethod供 auth.py 调用
UX 改进 (5 项)
UX-01 输入框样式+类型
- 密码输入框添加
focus:outline-none focus:ring-2 focus:ring-brand - 设置项 input type 映射:数值→
type="number" min="1",URL→type="url" - 所有动态渲染 input 统一添加 focus ring
UX-02 改密码 loading 状态
- 按钮点击后
disabled=true + textContent='提交中...' - 请求完成
finally块恢复
UX-03 加载失败 toast
loadSettings/loadTotpStatus/loadAllowlist的空 catch 改为console.error + toast
UX-04 保存失败回滚
saveSetting()失败时调用loadSettings()恢复原值
UX-05 IP 格式校验
- 前端正则校验:IP (
x.x.x.x) / CIDR (x.x.x.x/n) / 域名 - 后端
IpAllowlistRequestPydanticmodel_validator校验
验证结果
| 测试 | 结果 |
|---|---|
| SSRF localhost | ✅ 400 "不允许访问内网地址" |
| SSRF metadata | ✅ 400 "不允许访问内网地址" |
| 未知 key | ✅ 403 |
| INT 范围 99999 | ✅ 400 "范围: 1-1000" |
| INT 类型 "abc" | ✅ 400 "必须是整数" |
| 有效值 75 | ✅ 200 |
| IP 审计日志 | ✅ "添加 1 条手动 IP: 192.0.2.1" |
| TOTP schema | ✅ totp_code Optional 字段 |
| Input types | ✅ number/url/text 正确映射 |
是否需迁移/重启
- 需要重启后端服务(新增白名单+校验+SSRF 逻辑)