已开启
[Security] DELETE 和 GET Agent 接口获取了租户上下文但未做归属校验,存在越权访问风险 #50
张鑫宇创建于  6月15日
张鑫宇
张鑫宇成员
6月15日 创建

问题描述

server/main.py 中的 get_agent()delete_agent() 接口均调用了 get_tenant_context(request) 获取了当前租户的 user_idspace_id,但后续的 Manager 调用并未使用这些租户信息做过滤或校验

具体来说:

  1. get_agent()(第 277 行):获取 user_id, space_id 后,调用 manager.get_deployment(deployment_id) —— 该方法仅按 deployment_id 查询,没有任何租户过滤。若 Tenant A 知道 Tenant B 的 deployment_id,即可查看 B 的部署详情(包括 IP、端口等内部信息)。

  2. delete_agent()(第 313 行):同样获取了租户上下文但未使用,直接调用 manager.delete_deployment(deployment_id) 删除部署。Tenant A 可以删除 Tenant B 的 Agent 实例,造成服务中断。

  3. 接口的 docstring 明确写着「仅能访问/删除当前租户的部署」,但实际实现与文档描述不符。

影响范围

  • 多租户安全隔离被突破
  • 敏感信息(部署 URL、端口、运行时元数据)可能泄露
  • 恶意租户可删除其他租户的生产 Agent
  • 虽然当前 require_tenant=False(临时禁用租户验证),但即使将来开启验证后,上述漏洞仍然存在

修复建议

# 在 manager.get_deployment 或端点层增加租户过滤:
deployment = await manager.get_deployment(deployment_id)
if deployment and (deployment.user_id != user_id or deployment.space_id != space_id):
    raise HTTPException(status_code=404, detail="Deployment not found")

或者将 user_id/space_id 作为查询参数传入 get_deployment(),让 Manager 层负责过滤。

likedislike
openJiuwen-bot成员
6月15日 评论:

欢迎来到 openJiuwen 社区

Hey @xinyu-jiuwen , 感谢你对社区的贡献.

机器人使用手册

有关指令的使用,可以点击 此处 查看详情。开发人员可以在每个PR或Issue下方评论特定指令来触发机器人任务。

likedislike
Zziyifeihu
7月2日 关联了pull request:fix: validate tenant ownership before agent get/delete