Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-46558 — Plane 的 V2 资产子系统信任了工作区 slug 和资产 UUID,但未强制执行正确的成员权限检查,这导致一个已认证用户可以读取、复制、删除和覆盖其他工作区中的资产。 | Kitploit
工具/GitHubGitHub/0xmrma/cve-2026-46558
漏洞分析Web应用程序漏洞利用渗透测试论文与研究学习与教育精选资源
GitHub0xmrma/cve-2026-46558

CVE-2026-46558

Plane 的 V2 资产子系统信任了工作区 slug 和资产 UUID,但未强制执行正确的成员权限检查,这导致一个已认证用户可以读取、复制、删除和覆盖其他工作区中的资产。

查看仓库
22个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-46558

Plane 的 V2 资产子系统在缺乏正确成员关系检查的情况下,信任了用户提供的工作区 slug 和资产 UUID,这使得一个已认证用户可以读取、复制、删除和覆盖其他工作区中的资产。

简介

我在评审 Plane(开源项目管理平台)时发现了这个问题,带着一个非常具体的问题:

V2 资产端点是否实际实施了工作区隔离,还是过度信任了攻击者提供的工作区 slug 和资产 ID?

在这个案例中,答案是不。

Plane 的 V2 资产子系统暴露了两个相关的授权缺陷,破坏了任何已认证用户的工作区隔离:

  • 工作区级资产端点在执行资产操作之前,没有强制目标工作区的成员资格
  • 资产复制流程仅对目标工作区进行了授权,并信任了来源资产 UUID,而没有检查来源工作区的访问权限

这使得跨工作区资产滥用成为可能。

在我验证的概念验证(PoC)中,一个位于工作区 Bravo 的普通用户能够:

  • 下载 Alpha 的私有上传资产
  • 将该资产复制到 Bravo 的工作区中
  • 删除 Alpha 的原始资产
  • 用攻击者控制的内容覆盖 Alpha 的工作区标志

该问题后来被分配了 CVE-2026-46558。

Plane: Plane on GitHub
CVE: CVE-2026-46558

这影响了 Plane,根据其官方网站,该平台被全球 50,000 多个团队 使用。Plane 还强调了其强大的开源采用率,包括 46,000 多个 GitHub Star 和 1,000,000 多次 Docker 拉取,并展示了诸如 腾讯、埃森哲、微软 和 亚马逊 等组织。

photo0

攻击链

已认证的攻击者位于工作区 B → 工作区级 V2 资产路由信任目标工作区 slug 和资产 UUID,但缺少适当的成员关系检查 → 针对工作区 A 资产的预签名读取/补丁/删除操作 + 资产复制来源查找信任上传的 source UUID → 跨工作区泄露、复制、删除和品牌覆盖


Plane 的功能

Plane 是一个开源项目管理平台,用于管理:

  • 任务
  • 问题
  • 冲刺
  • 文档
  • 分类
  • 工作区级品牌和资产

这意味着其资产子系统位于真正的信任边界上。

这里重要的问题并不是 Plane 是否支持上传。

真正的问题是:

当一个已认证用户引用另一个工作区所拥有的资产时,Plane 是否会实施工作区隔离?

在这个案例中,答案是否定的。


为什么这个漏洞值得关注

许多多租户应用评审首先关注的是明显的管理员端点或直接的设置更新。

这忽略了一个非常常见且真实存在的漏洞类别:

通过共享文件或资产子系统进行次级对象访问

资产系统容易出错,因为它们通常结合了:

  • 用户控制的标识符
  • 存储层间接性
  • 元数据驱动的对象链接
  • 预签名 URL 生成
  • 共享路由后的多个实体类型

这正是租户边界被悄悄削弱的地方。

这个问题并非关于存储损坏。 也不是关于 S3 本身。 更不是关于上传 MIME 类型处理。

它属于 授权边界失败:

  • 攻击者控制的标识符跨越了边界
  • 服务器解析了跨工作区的对象
  • 授权不完整或缺失
  • 特权资产操作仍然成功

这就足以构成一个真正的漏洞。


我关注的边界

我没有通过盲目模糊测试随机端点或猜测 UUID 来接近 Plane。

更有效的方法是首先识别最有前景的隔离边界。

对于 Plane 来说,那就是 V2 资产子系统。

为什么?

因为共享资产系统在以下情况下会变得危险:

  • 存在多个工作区
  • 上传的对象通过 UUID 引用
  • 工作区 slug 是攻击者控制的路由输入
  • 应用程序随后将成功的查找转化为预签名下载或修改路径

那正是需要检查的边界。

而漏洞恰恰就存在于那里。


根本原因

这实际上是同一子系统中的两个相关授权失败。

根本原因 1:工作区资产路由缺少成员关系强制

工作区级资产路由通过以下代码暴露:

  • apps/api/plane/app/urls/asset.py:50-56

漏洞处理程序位于:

  • apps/api/plane/app/views/asset/v2.py:314
  • apps/api/plane/app/views/asset/v2.py:379
  • apps/api/plane/app/views/asset/v2.py:400
  • apps/api/plane/app/views/asset/v2.py:409

问题很简单。

WorkspaceFileAssetEndpoint 接受一个工作区 slug 和资产 UUID,然后直接解析对象,例如:

root@kitploit:~
workspace = Workspace.objects.get(slug=slug)

以及:

root@kitploit:~
asset = FileAsset.objects.get(id=asset_id, workspace__slug=slug)

而未首先强制调用者实际是该目标工作区的授权成员。

这意味着端点仍然可以:

  • 创建资产
  • 完成资产
  • 删除资产
  • 返回预签名下载 URL

针对另一个工作区的对象。

根本原因 2:资产复制信任了来源资产 UUID

资产复制路由通过以下代码映射:

  • apps/api/plane/app/urls/asset.py:100-101

漏洞逻辑位于:

  • apps/api/plane/app/views/asset/v2.py:736-780

目标工作区有一个授权装饰器。 但来源资产查找却没有。

来源对象使用以下代码加载:

root@kitploit:~
original_asset = FileAsset.objects.filter(id=asset_id, is_uploaded=True).first()

这意味着调用者只需要:

  • 对目标工作区的有效访问
  • 一个已上传的来源资产 UUID

没有检查调用者是否属于实际拥有该资产的来源工作区。

这就是第二个漏洞的全部。


为什么这是一个安全问题,而不仅仅是糟糕的访问逻辑

重要的区别在于跨工作区的影响。

许多授权错误被最小化为:

“它仍然需要登录”

这忽略了问题的核心。

真正的问题并非:

“调用者是否已认证?”

真正的问题是:

“调用者是否被授权访问具体的工作区和具体的资产?”

在 Plane 中,答案是否定的。

这将看起来像普通对象处理的行为,变成了一个真正的多租户安全问题。

存在明显的区别:

  • 在你自己工作区内的认证访问
  • 以及跨越另一个租户边界的认证访问

本问题明确属于第二种情况。


概念验证(PoC)

我本地在 Plane Community Edition 1.2.3 上针对两个不相关工作区中的两个普通用户验证了该问题:

  • Alpha 位于工作区 alpha-20260323072017
  • Bravo 位于工作区 bravo-20260323072017

我使用 Alpha 在一个项目问题中创建了一个合法的私有上传资产。

在我运行中验证的私有资产 ID 是:

root@kitploit:~
6ed6ed62-d1b2-4399-8220-336c01b7d72c

情况 1:未经授权从另一个工作区读取

作为 Bravo,我请求:

root@kitploit:~
GET /api/assets/v2/workspaces/alpha-20260323072017/6ed6ed62-d1b2-4399-8220-336c01b7d72c/

Plane 返回:

root@kitploit:~
HTTP/1.1 302 Found

以及 Alpha 资产的预签名下载 URL。

下载文件的哈希值与 Alpha 原始私有资产完全相同:

root@kitploit:~
original:          0d4d070f550ba59ba6b30bee62343cf68ea221af7034f131f72f6409cf5a598e
unauthorized read: 0d4d070f550ba59ba6b30bee62343cf68ea221af7034f131f72f6409cf5a598e

这证明读取路径成功跨越了工作区边界。


情况 2:通过来源 UUID 信任进行跨工作区复制

作为 Bravo,我随后请求:

root@kitploit:~
POST /api/assets/v2/workspaces/bravo-20260323072017/duplicate-assets/6ed6ed62-d1b2-4399-8220-336c01b7d72c/

Plane 返回:

root@kitploit:~
HTTP/1.1 200 OK

并创建了一个攻击者侧的复制资产:

root@kitploit:~
72d51497-ccc1-4546-ba14-28fae5d37dbb

复制文件的 SHA-256 与 Alpha 的原始资产完全相同:

root@kitploit:~
0d4d070f550ba59ba6b30bee62343cf68ea221af7034f131f72f6409cf5a598e

这证明仅凭来源资产 UUID 就足以将跨工作区内容复制到攻击者控制的工作区中。


情况 3:未经授权删除受害者资产

作为 Bravo,我随后发送:

root@kitploit:~
DELETE /api/assets/v2/workspaces/alpha-20260323072017/6ed6ed62-d1b2-4399-8220-336c01b7d72c/

Plane 返回:

root@kitploit:~
HTTP/1.1 204 No Content

当 Alpha 稍后获取该资产时,服务器返回:

root@kitploit:~
HTTP/1.1 404 Not Found

这证明了跨工作区的完整性影响,而不仅仅是信息披露。


情况 4:未经授权覆盖工作区标志

作为 Bravo,我通过易受攻击的工作区级资产路由,针对 Alpha 的工作区创建了一个 WORKSPACE_LOGO 资产,上传了攻击者控制的内容并完成了资产。

之后,Alpha 的工作区元数据指向了攻击者控制的标志资产:

root@kitploit:~
c1032f06-3cf5-4f7e-b139-e6976d8c567d

下载的最终标志哈希值与攻击者负载完全相同:

root@kitploit:~
expected: b9d1ef1de88d61bf55dd18055839bacacb832a752e17a7312547f641113d0e7b
observed: b9d1ef1de88d61bf55dd18055839bacacb832a752e17a7312547f641113d0e7b

这证明存在可见的跨工作区覆盖路径,而不仅仅是隐秘的后端访问问题。


为什么完整的攻击链很重要

上述任何一项结果都足以构成一个真正的漏洞报告。

但验证完整的攻击链之所以重要,有两个原因。

第一

它表明问题并不仅限于只读暴露。

相同的薄弱边界导致了:

  • 信息披露
  • 复制
  • 删除
  • 覆盖

这使得影响远强于狭义的“可以获取一个文件”的 IDOR。

第二

它表明两条代码路径是相关的,但各自独立重要。

一个缺陷直接暴露了工作区级资产操作。 第二个缺陷将已上传的资产 UUID 变成了通过复制实现的可重用外泄原语。

这使得整体安全故事更难被忽视。


范围验证

我验证的最明显的覆盖影响是:

  • WORKSPACE_LOGO

这是故意的,因为它易于验证并展示了明显的跨租户完整性失败。

但端点并不限于工作区标志。

易受攻击的工作区级资产流程也接受多种实体上下文,包括:

  • 项目封面
  • 用户图像
  • 问题内容
  • 页面内容
  • 评论内容

这很重要,因为它表明该漏洞是 结构性的,而不是局限于单个品牌字段。

我直接验证了工作区标志路径。 更广泛的代码路径强烈表明其他资产支持的上下文也暴露于相同的授权错误中。


严重性和分类

该问题被合理分类为 高。

公告分类如下:

  • CWE-862: 缺少授权
  • CWE-639: 通过用户控制键绕过授权
  • CVSS:
root@kitploit:~
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L

这个分类是合理的。

声明并非是一个未认证的攻击者可以从零开始攻陷 Plane。 声明是任何普通的已认证用户可以在 V2 资产子系统中跨越租户边界,并对其他工作区执行高影响力的资产操作。

这是一个真实且可辩护的多租户授权漏洞。


为什么这仍然值得报告

有些人低估已认证的跨租户漏洞,因为他们听到:

“攻击者已经需要一个账户了”

这并非一个严肃的辩护。

在多工作区软件中,普通已认证用户应该被 限制 在自己的授权范围内。

如果工作区 Bravo 中的一个低权限用户可以读取、复制、删除或覆盖工作区 Alpha 中的对象,那么工作区隔离就被破坏了。

这正是应用程序应该保护的安全属性。

尤其是在一个存储内部工作内容和品牌资产的项目管理平台中,这是一个具有实际机密性和完整性影响的重大问题。


修复分析

该问题在 Plane v1.3.1 中得到了修复。

v1.3.1 的发布说明清楚地描述了修复内容:

  • 为所有 WorkspaceFileAssetEndpoint 方法添加 @allow_permission
  • 将 DuplicateAssetEndpoint 的来源资产查找范围限定为调用者是活跃成员的工作区

这是正确的修复方向,因为它解决了两个失败的安全属性:

  1. 工作区级资产操作现在需要真正的成员关系强制
  2. 复制流程中的来源资产不再仅凭 UUID 被信任

这正是本漏洞所需要的。

一个好的修复并不在于更好地隐藏 UUID。 也不在于更改预签名 URL 的生成。

而在于恢复正确的规则:

工作区 slug 加上资产 UUID 永远不应该在缺少针对当前用户的授权范围时成为充分条件

这就是补丁所恢复的内容。


披露

该问题通过 GitHub 安全公告私下报告。

报告内容包括:

  • 两条代码路径的根本原因分析
  • 本地端到端概念验证
  • 原始 HTTP 证据
  • 基于哈希的未经授权下载、复制和覆盖证明
  • 修复建议

该问题后来被发布为:

  • GHSA-qw87-v5w3-6vxx
  • CVE-2026-46558

公告于 2026年5月15日 发布。 修复于 Plane v1.3.1 中交付。


这个漏洞真正教会我们什么

关键教训很简单:

共享资产子系统是授权边界,而不仅仅是存储辅助工具

许多开发者的思维模式是:

  • 上传成功
  • 对象存在
  • UUID 可解析
  • 预签名 URL 工作

这些是实现细节。

真正的安全问题是:

谁被允许跨租户边界解析、修改、复制或重新链接该资产?

在 Plane 中,这个边界并未得到一致实施。

这才是真正的要点。

这个漏洞也强化了评审多租户应用程序中一个重要方面:

  • 共享对象层值得直接的安全审查
  • 当授权不完整时,攻击者控制的标识符就足够了
  • 单个子系统可以同时暴露机密性和完整性失败

关键点

  • 资产端点是真正的多租户安全边界
  • 已认证访问并不等同于授权的跨工作区访问
  • 工作区 slug 和资产 UUID 本身永远不应是充分的
  • 当上游授权薄弱时,预签名下载生成会变得危险
  • 同时验证读取和写入后果会使授权报告更有力
  • 共享资产系统中的结构性授权错误通常会影响多个实体类型

结语

这个漏洞并不涉及奇特的存储行为。

它关乎提出正确的信任边界问题。

在 Plane 中,一个已认证用户可以提供另一个工作区的 slug 和资产 UUID,而 V2 资产子系统对这些标识符的信任超出了应有的限度。

这就是它成为 CVE-2026-46558 的原因。

已在 Plane v1.3.1 中修复。

下载工具