Files
Nexus/docs/changelog/2026-05-30-settings-security-ux.md
T
2026-07-08 22:31:31 +08:00

3.3 KiB
Raw Blame History

Changelog — Settings 安全加固 + UX 迭代

日期: 2026-05-30
Commit: a50f179
类型: 安全修复 + UX 改进
涉及文件:

  • server/api/settings.py — SSRF 防护 + key 白名单 + 值校验 + IP 审计
  • server/api/auth.py — 密码修改要求 TOTP
  • server/application/services/auth_service.py — _verify_totp staticmethod
  • web/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_ipsremove_allowlist_ip 缺少审计日志。

  • 两个端点添加 request: Request 参数
  • 添加标准 AuditLog 写入(action/detail/ip_address

S-09 改密码要求 TOTP (P1)

已启用 TOTP 的管理员改密码只需密码,可绕过 TOTP 保护。

  • ChangePasswordRequest 新增 totp_code: Optional[str]
  • change_password handler 检查:TOTP 已启用 + 未提供 code → 400
  • AuthService._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) / 域名
  • 后端 IpAllowlistRequest Pydantic model_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 逻辑)