fix(P1): 成片库越权漏洞修复-全链路加user_id校验 #573

Merged
auto-approve-bot merged 1 commits from fix/p1-video-library-authz into develop 2026-07-19 12:01:14 +08:00
Owner

问题

成片库按用户维度改造只加了列表页的user_id过滤,单条查询和写操作全部没有校验,存在水平越权:

  • 知道video_id就能看别人的视频详情
  • 知道video_id就能改别人的复核状态
  • 知道video_id就能删别人的视频
  • 批量删除/批量下载同样无校验

修复

全链路加user_id校验:

  • port接口层: get/update_review_status/get_by_ids/delete/batch_delete 加user_id可选参数(向后兼容)
  • repository实现层: 所有单条查询和写操作加user_id过滤条件
  • use_case层: GetGeneratedVideo/UpdateVideoReviewStatus/GetVideosByIds/GetGeneratedVideoDownloadUrl 加user_id透传
  • routes层: 5个接口全部传入current_user.user.id
    • GET /videos/{video_id} 单条详情
    • PATCH /videos/{video_id}/review 复核状态
    • DELETE /videos/{video_id} 删除
    • POST /videos/batch-delete 批量删除
    • POST /videos/batch-download 批量下载校验

向后兼容

user_id为None时不过滤,保持原有行为,不影响内部调用和测试。

## 问题 成片库按用户维度改造只加了列表页的user_id过滤,单条查询和写操作全部没有校验,存在水平越权: - 知道video_id就能看别人的视频详情 - 知道video_id就能改别人的复核状态 - 知道video_id就能删别人的视频 - 批量删除/批量下载同样无校验 ## 修复 全链路加user_id校验: - **port接口层**: get/update_review_status/get_by_ids/delete/batch_delete 加user_id可选参数(向后兼容) - **repository实现层**: 所有单条查询和写操作加user_id过滤条件 - **use_case层**: GetGeneratedVideo/UpdateVideoReviewStatus/GetVideosByIds/GetGeneratedVideoDownloadUrl 加user_id透传 - **routes层**: 5个接口全部传入current_user.user.id - GET /videos/{video_id} 单条详情 - PATCH /videos/{video_id}/review 复核状态 - DELETE /videos/{video_id} 删除 - POST /videos/batch-delete 批量删除 - POST /videos/batch-download 批量下载校验 ## 向后兼容 user_id为None时不过滤,保持原有行为,不影响内部调用和测试。

🚀 预览环境已部署

项目 详情
PR号 #573
预览链接 https://pr-573.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #573 | | 预览链接 | [https://pr-573.preview.xiaoxiajianji.com](https://pr-573.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia reviewed 2026-07-19 11:04:27 +08:00
xiaoxia left a comment
Author
Owner

LGTM

LGTM
xiaoxia force-pushed fix/p1-video-library-authz from 86e320d896 to 166f982b91 2026-07-19 11:17:25 +08:00 Compare
xiaoxia force-pushed fix/p1-video-library-authz from 166f982b91 to cc9e7dd25a 2026-07-19 11:20:39 +08:00 Compare
xiaoxia force-pushed fix/p1-video-library-authz from cc9e7dd25a to 2162f1c9f3 2026-07-19 11:29:05 +08:00 Compare
Collaborator

代码审查结果 - PR #573

⚠️ 问题(1个需要修改)

  1. apps/api/app/api/routes/videos.py 第151行batch_delete_videos 函数缺少对 request.video_ids 数量的上限校验
    • 问题描述:在同一个文件中的 batch_download_videos 函数(第188行附近)明确限制了单次批量操作最多50个视频(if len(request.video_ids) > 50),但 batch_delete_videos 函数缺少此校验。这可能导致用户一次性请求删除海量ID,引发数据库压力过大或DoS攻击。
    • 修改建议:参考 batch_download_videos 的实现,在函数开头添加 if len(request.video_ids) > 50: raise HTTPException(...)

💡 建议(3个可选)

  1. 测试覆盖度:建议增加针对“越权访问”的集成测试用例。目前的 tests/integration 中的 Stub 实现使用了 **kwargs 忽略了 user_id 参数,单元测试也仅验证了 user_id=None 的情况。建议添加测试用例模拟 UserA 尝试访问/删除 UserB 的视频,确保返回 404 而非成功。
  2. apps/api/app/api/routes/videos.py 第127行delete_video 函数中先通过 GetGeneratedVideoUseCase 查询,再调用 repo.delete。虽然逻辑正确(为了获取 OSS 路径),但这产生了两次数据库查询。如果性能敏感,可以考虑在 Repository 层实现 get_and_delete 原子操作,或者接受当前的冗余以换取代码清晰度。
  3. packages/adapters/sqlalchemy_impl/generated_video_repository.pyupdate_review_status 等方法在 model is None 时返回 None,上层统一抛出 404。这种“隐式地通过 404 掩盖 403(无权访问)”的做法在安全上是可接受的(防止枚举ID),但如果业务需要区分“资源不存在”和“无权访问”,可能需要调整返回值或异常类型。

格式检查通过 | 逻辑审查需修改 | ⚠️ 建议关注性能


🤖 由 AI 代码审查机器人自动生成 | 2026-07-19 11:36:09 | 模型:

## 代码审查结果 - PR #573 ### ⚠️ 问题(1个需要修改) 1. **apps/api/app/api/routes/videos.py 第151行**:`batch_delete_videos` 函数缺少对 `request.video_ids` 数量的上限校验 - **问题描述**:在同一个文件中的 `batch_download_videos` 函数(第188行附近)明确限制了单次批量操作最多50个视频(`if len(request.video_ids) > 50`),但 `batch_delete_videos` 函数缺少此校验。这可能导致用户一次性请求删除海量ID,引发数据库压力过大或DoS攻击。 - **修改建议**:参考 `batch_download_videos` 的实现,在函数开头添加 `if len(request.video_ids) > 50: raise HTTPException(...)`。 ### 💡 建议(3个可选) 1. **测试覆盖度**:建议增加针对“越权访问”的集成测试用例。目前的 `tests/integration` 中的 Stub 实现使用了 `**kwargs` 忽略了 `user_id` 参数,单元测试也仅验证了 `user_id=None` 的情况。建议添加测试用例模拟 UserA 尝试访问/删除 UserB 的视频,确保返回 404 而非成功。 2. **apps/api/app/api/routes/videos.py 第127行**:`delete_video` 函数中先通过 `GetGeneratedVideoUseCase` 查询,再调用 `repo.delete`。虽然逻辑正确(为了获取 OSS 路径),但这产生了两次数据库查询。如果性能敏感,可以考虑在 Repository 层实现 `get_and_delete` 原子操作,或者接受当前的冗余以换取代码清晰度。 3. **packages/adapters/sqlalchemy_impl/generated_video_repository.py**:`update_review_status` 等方法在 `model is None` 时返回 `None`,上层统一抛出 404。这种“隐式地通过 404 掩盖 403(无权访问)”的做法在安全上是可接受的(防止枚举ID),但如果业务需要区分“资源不存在”和“无权访问”,可能需要调整返回值或异常类型。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-19 11:36:09 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia added 1 commit 2026-07-19 11:54:43 +08:00
fix(test): 修复GetGeneratedVideoUseCase断言以匹配新的user_id参数
CI Build & Deploy Pipeline / Build Staging API Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production API Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (pull_request) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 17s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 28s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
AI Code Review / AI Code Review (pull_request) Failing after 37s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m27s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 29s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 2m51s
Auto Approve CI PRs / Auto Approve on CI Green (pull_request) Successful in 3m27s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m5s
Auto Merge CI PRs / Auto Merge on CI Green + Approved (pull_request) Successful in 6m31s
Preview Cleanup / Cleanup Preview Environment (pull_request) Failing after 1s
f0035296b2
xiaoxia force-pushed fix/p1-video-library-authz from 2162f1c9f3 to f0035296b2 2026-07-19 11:54:43 +08:00 Compare
auto-approve-bot approved these changes 2026-07-19 11:58:10 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-07-19 11:58:10 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot merged commit 55835c609f into develop 2026-07-19 12:01:14 +08:00
auto-approve-bot deleted branch fix/p1-video-library-authz 2026-07-19 12:01:14 +08:00
Sign in to join this conversation.