feat: harden phase 3 api security

This commit is contained in:
QiuSW
2026-07-03 10:34:37 +08:00
parent 1c5aa7845d
commit 0168aa30ba
19 changed files with 540 additions and 46 deletions
+25
View File
@@ -703,3 +703,28 @@
- 更新 `docs/06-tasks.md`:T-306 验收口径明确 P3 只登记媒体访问控制、完整测试补跑和过期订单口径。
- 验证:文档口径修正,无代码变更;执行 `git diff --check` 作为格式检查。
- 下一步:领取 T-306 Phase 3 对外 API 安全加固。
## 2026-07-03 T-306 Phase 3 对外 API 安全加固
- 状态:DONE
- 变更:
- `apps/api/generation.py`:重写 `download_image_input()` 安全边界;`image_url` 只允许 `http` / `https`,请求前解析域名并拒绝私有、回环、链路本地、保留、组播、未指定地址;手动跟随重定向并逐跳重校验;响应按 `IMAGE_URL_MAX_BYTES` 流式限长读取,超限 / 非图片 / 空内容均返回 `bad_request`,且发生在预扣点前。
- `apps/api/throttles.py` / `apps/api/exceptions.py`:新增生成接口按 API Key / 用户限流、认证失败按 IP 限流;DRF 429 统一返回 `rate_limited` 错误结构。
- `apps/api/authentication.py` / `apps/api/views.py`:无效 / 畸形 / 缺失 API Key 进入认证失败限流;生成标题、生成图片视图挂生成限流。
- `config/settings.py`:新增全局 `REST_FRAMEWORK` 安全默认(默认空认证 + 默认 `IsAuthenticated`,强制视图显式 opt-in)、限流 / `image_url` 下载 / 充值金额上限配置。
- `apps/api/serializers.py`:`RechargeCreateRequestSerializer` 增加 `RECHARGE_MAX_AMOUNT_CNY` 单笔金额上限校验。
- `apps/api/tests.py`:新增裸 `APIView` 不接受 Web session 默认认证、无效 Key 限流、生成接口限流、`image_url` 回环 / 云元数据 / 重定向到内网 / 超大响应拒绝且不扣点、合法公网图片下载、充值金额上限测试。
- 同步更新 `.env.example`、`README.md`、`docs/00-ai-start-here.md`、`docs/04-architecture.md`、`docs/api.md`、`docs/env.md`、`docs/06-tasks.md`、`docs/current-state.md`、`docs/project-brief.md`、`docs/project-onepager.md`。
- 验证:
- `py -3.12 -m py_compile config/settings.py apps/api/exceptions.py apps/api/generation.py apps/api/authentication.py apps/api/views.py apps/api/serializers.py apps/api/throttles.py apps/api/tests.py`:通过。
- `py -3.12 manage.py check`:通过,0 issues。
- `py -3.12 manage.py makemigrations --check --dry-run`:通过,No changes detected。
- `py -3.12 manage.py test apps.api.tests.ApiKeyAuthenticationTests.test_invalid_api_key_failures_are_throttled_by_ip apps.api.tests.GenerateApiTests.test_generate_endpoint_is_throttled_by_api_key_without_extra_charge --noinput --keepdb --verbosity 2`:通过,2 tests OK。
- `py -3.12 manage.py test apps.api --noinput --keepdb --verbosity 2`:通过,39 tests OK。
- `py -3.12 -m compileall apps config`:通过。
- `py -3.12 manage.py test apps.billing apps.api --noinput --keepdb --verbosity 2`:未作为绿灯;62 tests 跑到末尾,功能用例输出均为 ok,最后远程 MySQL 在并发扣点测试的 flush/重连阶段 reset 连接,报 `OperationalError (2013 Lost connection to MySQL server during query)`。
- `$env:MYSQL_CONNECT_TIMEOUT='90'; py -3.12 manage.py test apps.billing.tests.ConcurrentDebitTests --noinput --keepdb --verbosity 2`:通过,1 test OK。
- `./init.ps1`:通过,Python 3.12.3、依赖已满足、`manage.py check` 0 issues。
- `git diff --check`:通过,仅 Windows CRLF 提示。
- 阻塞:T-306 功能无阻塞;完整大套件仍受远程 MySQL 连接稳定性影响。生产真实支付仍需微信 / 支付宝商户密钥、证书与 SDK 配置;真实 AI 上游 smoke 仍需配置 `AI_KEY_ENCRYPTION_KEY` 并导入 AiModel/ModelAlias。
- 下一步:领取 T-501 注册 / 登录(allauth)。