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

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

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

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

工具目录

分类

查看所有分类
Loading categories
openlore-PoC — PoC — 通过 OpenLore 中未经净化的 LLM 派生域字段进行路径遍历(GHSA-5j8x-q7q6-58j5,CVE-2026-87001,CVSS 4.7)。 | Kitploit
工具/GitHubGitHub/squeeze440/openlore-poc
漏洞分析代码分析漏洞利用Web应用程序漏洞利用渗透测试论文与研究
GitHubsqueeze440/openlore-poc

openlore-PoC

PoC — 通过 OpenLore 中未经净化的 LLM 派生域字段进行路径遍历(GHSA-5j8x-q7q6-58j5,CVE-2026-87001,CVSS 4.7)。

查看仓库
7天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

OpenLore 规范生成写入器中通过未净化的 LLM 派生 domain 字段导致的路径遍历

CVE 状态: 已申请,待分配。此发现已发布为 GHSA-5j8x-q7q6-58j5。在 CVE 分配后,此仓库将重命名为 CVE-YYYY-NNNNN-openlore-PoC,并且此横幅将替换为 CVE 链接。

研究员Dostxodjayev Abdullox (@squeeze440)
安全公告GHSA-5j8x-q7q6-58j5
CVSS 3.14.7 (中危)
弱点CWE-22, CWE-73

OpenLore 规范生成写入器中通过未净化的 LLM 派生 domain 字段导致的路径遍历

摘要:控制 openlore generate 所分析仓库内容的攻击者,可以导致 OpenSpec 规范生成流水线将受攻击者影响的 Markdown 写入目标项目之外的任意文件系统路径,因为 Stage-3 LLM 提取调用返回的 domain 值被逐字用于构建规范的输出路径,且在 fs.writeFile 之前没有进行路径遍历净化,也没有进行路径限制检查。

产品

OpenLore(clay-good/OpenLore),npm 包 openlore,规范生成流水线(openlore generate / OpenSpec 格式生成器 + 写入器)。不是确定性的 analyze/orient/MCP 防护路径——根据项目自身的 README/规范(“LLM 仅在生成不可避免时使用(规范编写),绝不用于检索或防护路径”),这是项目中唯一一条有意将 LLM 纳入生成循环的代码路径。

测试版本

Git 提交 1f2de00dfe75530efb256320c374dce36607ee70(2026-07-31),package.json 版本 2.1.7。

估计的 CVSS v3.1

4.7 (中危) — CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N

  • AV:L — 触发方式是针对磁盘上的目录进行本地 CLI 调用(openlore generate),而非网络服务。
  • AC:H — 利用需要操作员在配置了提供商的情况下运行由 LLM 支持的 generate 命令(而非默认的防护路径),并且需要被分析仓库的间接提示注入实际使模型在 domain 字段中输出路径遍历字符串——这是攻击者可以影响但无法完全控制的条件。
  • UI:R — 操作员必须选择针对恶意仓库运行规范生成。
  • I:H / C:N / A:N — 该漏洞是一个写入原语,其内容部分由攻击者模板化,并落在项目之外攻击者选择的路径上;未证明其可读取机密数据或可靠地降低可用性,因此这些指标保守地设为 N。

详情

ExtractedService.domain(src/types/pipeline.ts:105)直接由 Stage 3 LLM 调用填充,该调用接收被分析仓库的原始文件内容,并要求返回一个服务的 JSON 数组:

  • src/core/generator/stages/stage3-services.ts:45-52 从 fileChunks[i](被分析仓库的字面源代码文本)构建提示,并调用 pipeline.llm.completeJSON<ExtractedService[]>(..., STAGE3_SERVICE_SCHEMA)。
  • src/core/generator/schemas.ts:100 — STAGE3_SERVICE_SCHEMA.items.properties.domain 为 { type: 'string' }:没有 pattern,没有 enum,没有允许列表。模型返回的任何字符串都会被接受。
  • src/core/generator/openspec-format-generator.ts:161 — const domainName = service.domain || this.inferDomain(...) 按原样使用该字符串。
  • src/core/generator/openspec-format-generator.ts:563 — path: \openspec/specs/${domain.name.toLowerCase()}/spec.md`normalizeDomainName()src/core/generator/openspec-compat.ts:655src/core/generator/openspec-writer.ts:167`,用于过期域目录比较)——但在此处从未被调用,而这里正是该值实际成为文件系统路径的唯一位置。

最终效果:诸如 ../../../../../../tmp/x 这样的 domain 值会从 LLM 的 JSON 响应原封不动地传递到真实的 writeFile 调用,完全落在被分析项目之外。这正是项目自身的 openspec/specs/mcp-security/spec.md 明确定义并针对 MCP/serve/view 表面进行加固的“仓库内容将写入重定向到项目根目录之外”威胁模型(safeJoin、符号链接感知限制、路径参数覆盖门)——而生成器/写入器表面根本没有等效的门。

概念验证

未进行实时 LLM 调用(模型对注入指令的遵从是概率性的,并非此漏洞的有趣部分);相反,PoC 使用真实的、未经修改的 OpenSpecFormatGenerator 和 OpenSpecWriter,并传入一个 PipelineResult,其唯一的 ExtractedService.domain 字段恰好持有 STAGE3_SERVICE_SCHEMA 目前允许 LLM 返回的字符串形状,也恰好是源文件注释指示“将 domain 设置为 ../../../.../tmp/x”可能从 Stage 3(它将原始文件内容传递给模型)引出的内容。

脚本:~/engagements/openlore/source/poc-domain-traversal.ts(测试克隆的仓库根目录),针对位于 ~/engagements/openlore/evidence/victim-project 的临时项目运行:

root@kitploit:~
cd ~/engagements/openlore/source
npx tsx poc-domain-traversal.ts

结果:OpenSpecFormatGenerator.generateSpecs()(未修改)生成一个域规范,其 path: "openspec/specs/../../../../../../../../../../../../../../../../../../../../tmp/openlore_traversal_proof/spec.md", 并且 OpenSpecWriter.writeSpecs()(未修改)将其写入——落在 /tmp/openlore_traversal_proof/spec.md,完全在 victim-project 根目录之外,而 victim-project/openspec/specs/ 始终只包含两个合法的 overview/architecture 目录。

截图(真实的 Xvfb+fluxbox+xterm 捕获,scrot -w <window id>):

  • ../evidence/poc-generator-write.png — PoC 运行:生成器包含路径遍历的原始 spec.path,写入器日志行 Wrote openspec/specs/../../.../tmp/openlore_traversal_proof/spec.md,以及脚本自身对 /tmp/openlore_traversal_proof/spec.md 存在且包含受攻击者影响内容的确认。
  • ../evidence/poc-outside-fs-proof.png — 独立确认:对 victim-project/openspec/specs/ 执行 ls 仅显示 architecture/overview(项目内没有恶意域的任何痕迹),而对 /tmp/openlore_traversal_proof/ 执行 ls -la 显示逃逸的 spec.md 直接位于 /tmp 下。

影响

能够诱使目标针对其编写的仓库运行 openlore generate(由 LLM 支持的规范生成)的攻击者——对于一个明确用途是指向第三方/不受信任代码库的 CLI 工具来说,这是一个合理的场景——可以将包含受攻击者影响内容的文件写入操作员操作系统用户可写入的任何路径,仅受逃逸所需的 ../ 段数量以及文件系统权限的限制。该写入未被确认可直接执行,但足够浅的项目路径可能让路径遍历到达同一账户上被其他工具执行或自动加载的位置(shell rc 文件、cron 用户目录、编辑器/IDE 配置),这一点未经测试,此处也不作声称。

弱点

  • CWE-22:对路径名的限制不当导致受限目录遍历(“路径遍历”)
  • CWE-73:文件名或路径的外部控制
  • CWE-20:输入验证不当(根本原因——LLM 的 JSON 输出被当作内部生成的内容一样信任)

修复建议

  1. 在首次从 LLM 响应接受 domain.name / service.domain 的位置(openspec-format-generator.ts 中的 groupByDomain())应用现有的 normalizeDomainName()(或等效的允许列表正则,例如 ^[a-z][a-z0-9-]{0,63}$),而不仅仅是在稍后的过期目录比较位置。
  2. 将 OpenSpecWriter.writeSpec() 的 fullPath 计算通过项目自身的 safeJoin()(src/utils/path-confinement.ts)路由,而不是普通的 node:path.join,与此代码库中所有其他不受信任路径表面已经要求的限制保持一致。
  3. 为 STAGE3_SERVICE_SCHEMA.domain(以及任何其他稍后用于构建文件系统路径的 schema 字段)添加 pattern 约束,以便强制执行结构化输出 schema 的提供商会直接拒绝不符合的值。
  4. 添加回归测试——本着现有 MCP“路径参数覆盖门”的精神——断言包含 或在 之外解析的 在 接触文件系统之前被拒绝。

致谢

Dostxodjayev Abdullox

报告渠道

此仓库已启用 GitHub 私密漏洞报告:https://github.com/clay-good/OpenLore/security/advisories/new(标准 GHSA 流程)。在此审计之前,通过 gh api repos/clay-good/OpenLore/security-advisories 返回 [](无先前公告)确认。

下载工具
将其直接插值到规范声明的输出路径中。注意
(
)存在于同一文件的依赖图中,并且在其他地方被应用(
  • src/core/generator/openspec-writer.ts:248 — const fullPath = join(this.rootPath, spec.path); 使用普通的 node:path.join,它会按词法解析 ../ 段,且没有调用项目自身的 safeJoin()(src/utils/path-confinement.ts),而根据 openspec/specs/mcp-security/spec.md,此代码库中所有其他不受信任路径的表面(MCP 处理器、openlore view 的 /api/skeleton 和 /api/spec-requirements)都必须通过该方法路由。
  • src/core/generator/openspec-writer.ts:277 / :294 随后执行 writeFile(fullPath, spec.content, 'utf-8'),并且 ensureDir()(openspec-writer.ts:497-499)在同一未受限路径上执行 mkdir(dirname(filePath), { recursive: true }),在离开项目根目录的过程中创建任何缺失的中间目录。
  • ..
    rootPath
    GeneratedSpec.path
    OpenSpecWriter