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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2026-33146 — 公共分享在页面树中看起来是干净的,但搜索端点却揭示了另一番景象。在Docmost中,隐藏在公共分享视图中的受限子页面仍然可能通过公共分享搜索结果泄露。 | Kitploit
工具/GitHubGitHub/0xmrma/cve-2026-33146
漏洞分析信息收集Web安全渗透测试论文与研究学习与教育
GitHub0xmrma/cve-2026-33146

CVE-2026-33146

公共分享在页面树中看起来是干净的,但搜索端点却揭示了另一番景象。在Docmost中,隐藏在公共分享视图中的受限子页面仍然可能通过公共分享搜索结果泄露。

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

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-33146

一个公开分享在页面树中看起来是干净的,但搜索端点却讲述了不同的故事。在 Docmost 中,向公开分享查看器隐藏的受限子页面仍可能通过公开分享搜索结果泄露。

简介

我在审查 Docmost(一个开源协作维基和文档平台)时发现了这个问题,脑海中有个非常简单的问题:

如果一个页面有意对公开分享查看器隐藏,那么每个公开功能是否都尊重相同的限制边界?

在这种情况下,答案是否定的。

一个受限的子页面可以隐藏在公开分享树中,同时仍通过公开分享搜索端点泄露。

该问题已被接受并分配了 CVE-2026-33146。

Docmost: GitHub 上的 Docmost
CVE: CVE-2026-33146

Docmost 的官方站点将其描述为一个企业级的本地部署维基,拥有 300 万+ 下载量,并声称受到包括 维尔纽斯市、Bechtle、澳大利亚政府、红十字会 和 ETS Quebec 在内的组织团队的信任。

photo0

攻击链

启用了子页面的公开父级分享 → 受限后代从公开树中隐藏 → 攻击者查询公开分享搜索 → 受限子页面的标题和摘要泄露


Docmost 的功能

Docmost 是一个协作维基和文档平台。

它提供:

  • 共享页面
  • 公开分享链接
  • 嵌套页面树
  • 工作区和空间级别的内容组织
  • 跨共享内容的搜索

这意味着其公开分享模型是一个真正的安全边界。

这里的重要问题并非是 Docmost 能否公开分享页面。

真正的问题是:

当 Docmost 决定某个后代页面受限且不应显示给公开分享访问者时,这种限制在公开分享流程中是否处处生效?

在这种情况下,它并没有。


为什么这个漏洞值得关注

很多安全审查在看到一个页面在 UI 中被隐藏时就过早停止了。

这还不够。

更强的问题是:

每个后端路径是否都执行相同的可见性决策?

这之所以重要,是因为安全边界不是由界面看起来如何定义的。
它们是由服务器实际返回的内容定义的。

在这里,公开树端点是安全地运行的:

  • 受限后代被隐藏了

但公开分享搜索路径的行为不同:

  • 受限后代仍然影响结果
  • 它们的标题泄露了
  • 它们的高亮内容摘要泄露了

这使得这成为一个真正的授权和信息泄露问题,而不仅仅是呈现不一致。


我关注的核心边界

我并没有通过随机模糊测试路由并希望出现有趣的结果来接近 Docmost。

更强的方法是先选择一个信任边界。

对于支持以下功能的应用:

  • 公开分享
  • 嵌套对象
  • 每页面限制
  • 内容搜索

最好的问题之一是:

搜索层是否强制执行与浏览层完全相同的授权边界?

当以下情况时,这个问题变得特别有价值:

  • 父对象是公开的
  • 后代有不同的可见性规则
  • 搜索是通过单独的服务路径实现的

这正是该问题出现的地方。


根本原因

这个错误并非 Docmost 未能将受限页面隐藏在正常的公开树中。

错误在于 公开搜索并未尊重相同的限制逻辑。

从源码审查来看,公开树流程使用了受限感知的后代遍历。

相关区域:

  • apps/server/src/core/share/share.service.ts

该路径通过使用以下方式有意排除受限后代:

  • getPageAndDescendantsExcludingRestricted(...)

但公开分享搜索流程走的是不同的路径。

相关区域:

  • apps/server/src/core/search/search.controller.ts
  • apps/server/src/core/search/search.service.ts

在那里,代码使用以下方式收集后代:

  • getPageAndDescendants(...)

这意味着受限后代仍在搜索范围内。

在公开分享上下文中,这一点非常重要,因为搜索分支是在没有正常经过身份验证的用户权限上下文的情况下运行的。因此,一旦受限后代被包含在可搜索页面集合中,它们的元数据便可能通过响应泄露。

为何可被利用

因为攻击者不需要经过身份验证的账户。

他们只需要:

  • 一个有效的公开分享密钥
  • 分享中包含子页面
  • 知道或能够猜测可能出现在隐藏后代中的搜索词

一旦满足该条件,公开访问者就可以查询分享搜索端点并恢复:

  • 隐藏的页面标题
  • 高亮显示的正文摘要
  • 证明在共享父页面下存在受限子页面

即使未返回完整页面正文,这也足以造成机密性泄露。


为何这是一个安全问题,而非仅仅是端点行为不同

重要的区别在于,应用程序已经清晰地表明了预期的安全模型。

公开树端点隐藏了受限后代。

所以真正的问题不是:

“搜索是否恰好返回了更广的结果集?”

真正的问题是:

“搜索是否违反了已在同一公开分享边界其他位置执行的授权决策?”

在 Docmost 中,是的。

这就把这从一个问题:

  • 功能不一致

变成了:

  • 访问控制执行不一致

这就是为什么这是一个真正的漏洞。


PoC

我通过并排比较两个相关的公开端点来验证该问题。

情况 1:公开树正确隐藏了受限子页面

首先,我使用公开分享密钥测试了正常的公开树端点。

示例请求:

root@kitploit:~
POST /api/shares/tree HTTP/1.1
Host: 127.0.0.1:6752
Content-Type: application/json

{
  "shareId": "public-share-key"
}

响应仅返回了页面树中的公开子页面。

代表性结果:

root@kitploit:~
{
  "pageTree": [
    {
      "id": "public-child",
      "title": "Public roadmap"
    }
  ]
}

这确立了预期的产品行为:

  • 受限子页面被有意向公开访问者隐藏

情况 2:公开分享搜索仍然泄露了受限子页面

然后我使用出现在受限后代中的术语查询了公开分享搜索端点。

示例请求:

root@kitploit:~
POST /api/search/share-search HTTP/1.1
Host: 127.0.0.1:6752
Content-Type: application/json

{
  "shareId": "public-share-key",
  "query": "salary"
}

响应仍然包含了受限子页面:

root@kitploit:~
{
  "items": [
    {
      "id": "public-child",
      "title": "Public roadmap",
      "highlight": "release plan and milestones"
    },
    {
      "id": "restricted-child",
      "title": "Payroll Q4",
      "highlight": "salary bands and bonus targets"
    }
  ]
}

这证明了核心主张:

  • 受限子页面在公开树中被隐藏
  • 但仍然通过公开分享搜索泄露

为何这两个复现很重要

这个问题最强有力的部分并非第二个请求本身。

而是两个端点之间的对比。

首先

它表明产品已经为公开分享设定了预期的限制模型。

受限后代不应被公开访问者看到。

其次

它证明搜索路径打破了完全相同的边界。

这使得该问题更难被当作预期的搜索行为或文档缺口来驳回。

应用程序本身通过树响应建立了规则,然后又通过搜索响应违反了它。

这是强有力的证据。


泄露实际上给了攻击者什么

这个问题不会暴露整个工作区中的任意内容。

其范围比那要窄。

但在受影响的公开分享子树内,它仍然给攻击者提供了有用的未经授权信息:

  • 隐藏的文档标题
  • 来自隐藏内容的高亮摘要
  • 确认存在受限后代
  • 取决于文档内容,关于薪资、法律、规划、凭据或内部操作的线索

即使是简短的摘要也可能很重要。

像这样的标题:

  • 薪资
  • 招聘计划
  • 法律草案
  • 客户事件
  • 凭据轮换

已经为攻击者创造了安全价值。

因此,尽管这最终被归类为 中等,但它仍然是一个有效的机密性问题,具有清晰且可辩护的边界突破。


严重性和分类

该问题被分配了:

  • CVE-2026-33146

安全公告的严重性为:

  • 中等
  • CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:N/A:N

该评分反映的是较窄的机密性泄露,而非完全的未经授权文档访问。

重要的一点是,该问题仍然是有效的。

这里的主张并非:

  • 完整页面读取
  • 任意工作区披露
  • 完整性影响
  • 可用性影响

而是:

  • 一个公开分享访问者能够从产品有意在相同公开分享流程中其他位置隐藏的受限子页面中检索元数据

这是一个真正的与授权相关的信息泄露。


为何这仍然值得报告

有些人太快地忽略了元数据泄露。

这是个错误。

真正的问题是泄露的数据是否越过了预期的边界。

在这里,是的。

如果应用程序说:

  • 这个受限子页面不应向公开分享查看者可见

但一个公开端点仍然泄露了:

  • 它的标题
  • 部分内容

那么机密性模型已经失败,即使影响有限。

这使得它值得报告。

像这样干净、范围明确且可复现的 bug 正是那种有助于展示强安全审查判断的问题。


修复分析

最安全的修复方向是让公开搜索使用与公开树流程相同的受限感知后代逻辑。

在实践中,这意味着分享搜索分支不应使用以下方式枚举后代:

root@kitploit:~
getPageAndDescendants(...)

而应调整为更安全的公开分享遍历方法,使用:

root@kitploit:~
getPageAndDescendantsExcludingRestricted(...)

另一种修复方式是保持更广泛的枚举,然后在搜索查询返回结果之前显式过滤掉受限后代。

但更干净的设计很简单:

搜索边界应与浏览边界匹配

这正是失败的安全属性。


披露

该问题通过 GitHub 的安全报告流程私下报告。

报告显示了:

  • 通过 /api/shares/tree 的预期安全行为
  • 通过 /api/search/share-search 的不一致脆弱行为
  • 底层的源码级别原因
  • 具体的复现路径

该问题已被接受并分配了:

CVE-2026-33146

最终安全公告的严重性为 中等,这比更广泛的严重性声明更符合较窄的泄露范围。

这并不会削弱该发现的有效性。

它只是更精确地定义了其影响。


这个 bug 真正教会我们什么

这里的关键教训很简单:

在一个公开端点中隐藏某物是不够的,如果另一个公开端点仍然泄露它。

许多开发者只考虑明显渲染路径中的授权:

  • 页面树
  • 页面视图
  • 主 UI

但真正的边界要更广。

你还必须问:

  • 搜索是否尊重相同的规则?
  • 侧信道是否尊重相同的规则?
  • 元数据响应是否尊重相同的规则?

在 Docmost 中,答案是否定的。

这才是真正的要点。


关键点

  • 公开分享功能必须在浏览和搜索路径中执行相同的可见性模型
  • 当元数据泄露越过预期的授权边界时,它们仍然很重要
  • 并排端点比较使此类问题更有说服力
  • 如果受限后代对同一公开查看者隐藏,则它们绝不应保持可搜索
  • 范围狭窄并不会使有效的 bug 不值得报告
  • 好的安全审查通常在于测试一致性,而不仅仅是发现崩溃或完全绕过

结语

这个漏洞并非关于花哨的 payload 或复杂的利用链。

而是关于提出一个非常实际的信任边界问题。

Docmost 在一个地方隐藏了受限页面。
然后在另一个地方泄露了它。

这就是为什么这成为了 CVE-2026-33146。

下载工具