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

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

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

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

工具目录

分类

查看所有分类
Loading categories
terrapod-PoC — PoC — Terrapod 中平台级 GPG 信任锚存储缺少授权(GHSA-6qrc-597p-mrp9,CVE-2026-87006,CVSS 6.5)。 | Kitploit
工具/GitHubGitHub/squeeze440/terrapod-poc
身份验证与授权漏洞分析漏洞利用Web安全渗透测试供应链安全论文与研究
GitHubsqueeze440/terrapod-poc

terrapod-PoC

PoC — Terrapod 中平台级 GPG 信任锚存储缺少授权(GHSA-6qrc-597p-mrp9,CVE-2026-87006,CVSS 6.5)。

查看仓库
1919天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Terrapod:安全公告

CVE 状态: 已申请,等待分配。此发现已发布为 GHSA-6qrc-597p-mrp9。CVE 分配后,此仓库将重命名为 CVE-YYYY-NNNNN-terrapod-PoC,并且此横幅将替换为 CVE 链接。

研究员Dostxodjayev Abdullox (@squeeze440)
公告GHSA-6qrc-597p-mrp9
CVSS 3.16.5(中危)
弱点CWE-862, CWE-284

摘要

Terrapod(main @ b36d953,post-v1.3.1)中 GPG 密钥管理 API 存在缺失授权漏洞,允许任何已认证主体——包括仅具有内置 everyone 角色且零能力授予的用户,或作用域受限的 runner token——通过 POST /api/terrapod/v1/gpg-keys 和 DELETE /api/terrapod/v1/gpg-keys/{key_id} 在平台范围的 GPG 信任锚存储中创建和删除条目,该存储用于验证发布到私有 registry 的每个 provider 的签名。

产品

Terrapod(mattrobinsonsre/terrapod)——自托管的 Terraform Enterprise / HCP Terraform 替代品。

测试版本

提交 b36d9535dedc31d85a02093d78f04da748492a2d(main),领先最近的发布标签 v1.3.1 10 个提交。(v1.3.2 作为标签存在,但位于 release/v1.3 分支上,尚未合并到 main;该 bug 在两个分支上都存在。)

估计 CVSS v3.1

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

PR:L(而非 N):每个请求仍然需要有效凭证——会话、API token,甚至运行作用域的 runtok: runner token——只是不需要特权凭证。I:H/C:N/A:N:该 bug 允许非特权调用者破坏 registry 共享签名密钥信任存储的完整性(删除合法密钥、插入自己的密钥),但本身不会泄露密钥材料(私钥从不在任何响应中序列化)或使服务离线。

详情

services/terrapod/api/routers/gpg_keys.py 实现了 GPGKey 行的 CRUD——Terrapod 信任的 ASCII 装甲公钥,用于验证发布到私有 registry 的每个 provider 版本上的分离式 SHA256SUMS.sig(services/terrapod/services/registry_provider_service.py:191-201,_verify_and_store_shasums_signature)。该 router 中的每个路由仅由 Depends(get_current_user) 门控——即“某个已认证主体”——完全没有角色或能力检查:

  • create_gpg_key_endpoint — services/terrapod/api/routers/gpg_keys.py:104-130
  • list_gpg_keys_endpoint — gpg_keys.py:133-146
  • show_gpg_key_endpoint — gpg_keys.py:149-166
  • revoke_gpg_key_endpoint — gpg_keys.py:168-193
  • delete_gpg_key_endpoint — gpg_keys.py:195-213

底层服务函数(services/terrapod/services/gpg_key_service.py:144 create_gpg_key、:316 delete_gpg_key)完全不接受调用者/所有权参数——GPGKey 没有命名空间或所有者列(_gpg_key_to_jsonapi 硬编码 "namespace": "default";创建时接受的 namespace 字段由请求模型解析,但从未传递)。密钥集是整个平台的一个全局共享列表。

将此与同一代码库中所有其他管理员拥有的平台资源进行对比——tokens.py、roles.py、vcs_connections.py、role_assignments.py——它们都将变更路由门控在 require_admin 或显式的 bound_to == user.email or is_admin 所有权检查之后。gpg_keys.py 是 api/routers/ 中唯一一个管理平台范围安全关键资源却没有任何此类保护的 router。

影响链:get_gpg_key_by_key_id()(registry_provider_service.py:195)执行全局、无作用域查找——任何曾经注册的密钥,由任何人注册,都是任何 provider 发布的有效信任锚(这是自助发布者密钥注册的设计——错误消息甚至说 add it via /api/terrapod/v1/gpg-keys first)。由于注册没有认证检查,删除也没有认证检查:

  1. 任何已认证用户(或泄露/被观察到的 runner token,require_non_runner 的存在正是为了根据其在 services/terrapod/api/dependencies.py:387-400 中的 docstring 将其排除在“资源创建和管理端点”之外,但此 router 从未使用它)可以删除任何其他租户注册的签名密钥,破坏该租户已发布的每个 provider 版本的签名验证——一种跨租户完整性攻击,与目标命名空间零关系。
  2. 同一调用者可以注册新的受信任密钥,扩展平台的共享信任锚集,除了拥有任何凭证外没有任何门控。

项目自己的测试套件记录了这一缺口而没有质疑它——services/tests/api/test_gpg_keys.py 使用 AuthenticatedUser(roles=["everyone"], ...) 构建其创建/删除/撤销的 happy-path 测试(参见 _user(),第 23 行,在 TestCreate/TestDelete/TestRevoke 中全程使用),并为该非特权用户断言 201/204——即测试将易受攻击的行为断言为正确,它们只是从未被编写来询问“everyone 是否应该被允许这样做?”

概念验证

针对真实应用程序动态验证(通过项目自己的 docker-compose.test.yml 集成测试框架使用真实 Postgres + Redis——无 mock,无对应用代码的无关修改):

  1. 编写 services/tests/integration/test_gpg_key_missing_authz_poc.py:
    • test_everyone_role_user_can_delete_admins_signing_key — 一个 admin 通过 POST /api/terrapod/v1/gpg-keys 注册真实的 RSA-2048 PGP 公钥(201,确认存在于 Postgres 中),然后第二个仅以 roles=["everyone"] 认证的用户(无 admin,无能力授予)发送 DELETE /api/terrapod/v1/gpg-keys/{key_id} 并成功(204);之后确认该行已从 Postgres 中消失。
    • test_everyone_role_user_can_register_new_trusted_key — 同一非特权用户通过 POST /api/terrapod/v1/gpg-keys 注册全新密钥(201)。
  2. 构建测试镜像并针对真实基础设施运行:
    docker build -f docker/Dockerfile.test -t terrapod-test:local .
    docker compose -f docker-compose.test.yml run --rm test \
      pytest tests/integration/test_gpg_key_missing_authz_poc.py -v -m integration
    
    结果:2 passed — 两个断言(未授权删除成功,以及该行确实从真实数据库中消失)均成立。截图:evidence/gpg_key_authz_poc_run3.png。

影响

Terrapod 实例的任何已认证用户——无论角色、工作区访问权限或 registry 权限,低至内置非特权 everyone 角色或单次运行的作用域 runner token——都可以篡改平台的共享 GPG 信任锚存储:删除另一个团队注册的签名密钥(破坏他们已发布的每个 provider 版本的 terraform init 签名验证,平台范围)和/或将新密钥添加到受信任集。这破坏了项目作为头条功能宣传的“GPG 签名的私有模块 + provider registry”供应链保证,而攻击者无需任何工作区或 registry 特权。

弱点

  • CWE-862:缺失授权
  • CWE-284:不当访问控制

修复

向 services/terrapod/api/routers/gpg_keys.py 中的变更路由添加能力/角色门控,匹配 tokens.py/roles.py/vcs_connections.py 已使用的模式——例如在 create_gpg_key_endpoint、delete_gpg_key_endpoint 和 revoke_gpg_key_endpoint 上使用 Depends(require_admin)(revoke 通过要求有效的自撤销证书单独保护,但仍不应被任意调用者用于其他租户的密钥)。list/show 风险较低(装甲块按设计是公钥),但为了保持一致,可能也应至少要求 require_non_runner。如果自助式按命名空间的发布者密钥是预期模型,还应考虑在 GPGKey 上引入命名空间/所有者列,以便命名空间所有者只能管理自己的密钥,而不是单一的全局列表。

致谢:Dostxodjayev Abdullox

报告渠道:根据 SECURITY.md,请勿打开公开 issue。使用 GitHub 的私有漏洞报告:访问 https://github.com/mattrobinsonsre/terrapod/security/advisories/new,点击“Report a vulnerability”,并填写描述、复现步骤和受影响版本。(如果 PVR 不可用,政策规定直接向维护者发送电子邮件。)

下载工具