Files
ystp/docs/security.md
237899745 64b1169e8c
Some checks failed
CI / verify (push) Has been cancelled
feat: add runtime policy and observability
2026-07-25 20:00:11 +08:00

131 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 安全与风控设计 - ImageForge
目标:在“上传文件 + 对外 API + 计费”场景下,将最常见、最致命的安全与滥用风险前置到设计阶段,确保后续实现时有统一口径。
---
## 1. 威胁模型(摘要)
核心资产:
- 用户账号、API Key、订阅与账单数据
- 计算资源CPU/内存/带宽/存储)与服务可用性
- 用户上传图片(可能包含隐私/商业机密)
主要攻击面:
- 上传入口文件炸弹、DoS、恶意内容、路径/存储穿越)
- 认证入口撞库、弱密码、Token 泄露)
- API Key盗用、重放、暴力猜测
- Webhook伪造事件、重放、乱序
- 管理后台(权限越权、配置投毒)
---
## 2. 认证与会话
### 2.1 用户登录
- 密码哈希:`argon2id`(独立 salt哈希与校验在阻塞线程池执行不占用 Tokio I/O 线程。
- 登录保护:登录按 IP 限制为 5 分钟 30 次、按账号限制为 5 分钟 10 次;注册按 IP 限制为每小时 10 次。
- 找回密码按 IP/邮箱双维度限速,验证和重置链接也有独立尝试上限。
- 账号状态:`is_active=false` 直接拒绝登录与 API。
### 2.2 JWT 使用建议
- 对外 API支持 Bearer Token适合 CLI/SDK
- 网站Vue3优先使用 HttpOnly Cookie 承载会话(降低 XSS 泄露风险),如使用 localStorage 必须配合严格 CSP。
- JWT 包含用户 `token_version`;修改或重置密码会递增版本,使此前签发的 JWT 立即失效。
---
## 3. API Key 安全
### 3.1 Key 生成与展示
- Key 仅在创建时展示一次(前端明确提示“请立即保存”)。
- Key 前缀(`key_prefix`)用于列表展示与快速检索。
### 3.2 Key 存储与校验
推荐:`key_hash = HMAC-SHA256(full_key, API_KEY_PEPPER)`,只存 hash不存明文。
理由:
- 校验快,适合高 QPS
- pepper 作为服务器秘密(配置/密钥管理系统),泄露风险可控;
- 避免 bcrypt/argon2 用在高频 key 校验导致性能瓶颈。
### 3.3 权限与限制
- API Key 请求会执行 `permissions` 校验;`compress` 权限兼容同步、批量、任务查询和结果下载。
- 每个 API Key 使用数据库中的 `rate_limit` 执行 Redis 原子分钟限速。
- 支持禁用/轮换;可选 IP 白名单Business/V1+)。
- 每次请求记录 `last_used_at/last_used_ip/user_agent`(审计)。
### 3.4 运行时策略
- 管理后台 `system_config` 中的 `features``rate_limits``file_limits` 会在最多 5 秒缓存后生效,无需重启服务。
- 功能开关可控制注册、匿名上传和 API Key 的创建及使用;环境变量 `ALLOW_ANONYMOUS_UPLOAD=false` 是不可被后台重新开启的上层硬限制。
- 限速配置覆盖匿名、登录用户、API Key、登录、注册、邮件验证和密码重置入口API Key 自身限制与全局限制取较小值。
- 配置更新会校验数值边界并写入 `audit_logs`,审计记录不包含密钥明文。
---
## 4. 上传与图片处理安全
### 4.1 输入校验
- 只依赖扩展名不安全:必须校验魔数/探测真实格式。
- 单文件上传按套餐上限分片读取;批量上传边接收边落盘,不在 API 内存中累计整批文件。
- multipart 文本字段与字段数量单独设限,文件名清除控制字符并按数据库长度安全截断。
- 设定上限:
- `max_file_size_mb`
- `max_pixels`(宽×高)
- `max_dimension`(单边)
- 图片处理全局并发信号量
### 4.2 资源隔离
- 压缩属 CPU 密集型:放到 WorkerAPI 只做编排与轻量校验。
- Worker 限制并发:按“用户/套餐”与“全局”双维度控制。
- 对异常图片:快速失败并记录审计与指标(格式错误/像素超限/解码失败)。
### 4.3 元数据(隐私)
- 默认移除 EXIF定位/设备信息),除非用户明确开启 `preserve_metadata=true`
- UI 必须清晰提示该开关的隐私含义。
---
## 5. 计费风控(防盗刷/滥用)
- **幂等**`Idempotency-Key` 防止重试导致重复扣费。
- **配额硬限制**:到达当期额度返回 `QUOTA_EXCEEDED`HTTP 402
- **匿名试用**:每日 10 次,采用 **Cookie + IP** 双维度 Redis 原子预留;处理失败归还,已进入正常处理的不可压缩图片同样计次。
- **异常检测**(告警即可,首期不必自动封禁):
- 短时间内用量突增
- 失败率异常升高(疑似 fuzzing/探测)
- 单 Key 多 IP 快速切换
---
## 6. Webhook 安全
必须要求:
- 验签provider 签名 + webhook secret
- 事件幂等:按 `provider_event_id` 去重。
- 重放保护:记录 `received_at` 与处理状态,拒绝重复处理。
- 最小暴露webhook 路由不接受浏览器跨域调用,不返回敏感信息。
---
## 7. Web 安全(前端/网关)
### 7.1 HTTP 安全头(建议由 Nginx 设置)
- `Strict-Transport-Security`
- `Content-Security-Policy`(至少限制脚本来源;如用第三方支付跳转按需放开)
- `X-Content-Type-Options: nosniff`
- `Referrer-Policy`
- `Permissions-Policy`
### 7.2 CORS 策略
- 若前后端同域:尽量不启用宽松 CORS。
- 若分离部署CORS 白名单仅放行前端域名;对 `/webhooks/*` 禁止 CORS。
---
## 8. 数据安全与保留
- 结果保留期:未登录/Free 1 天、Pro 7 天、Business 15 天,实际值由套餐的 `retention_days` 决定。
- 支持用户主动删除任务/文件(立即删除对象存储 + DB 标记/审计)。
- 审计日志留存与脱敏保留必要字段IP、UA、动作、对象 ID避免写入明文密钥/Token。