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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2026-64640 — 复现器利用 Apache Polaris Iceberg REST 在位置验证之前发放凭证的漏洞,证明存在跨租户云读取和桶存在性预言问题。 | Kitploit
工具/GitHubGitHub/oscerd/cve-2026-64640
侦察漏洞分析漏洞利用Web应用程序漏洞利用数据泄露渗透测试云安全API 安全
GitHuboscerd/cve-2026-64640

CVE-2026-64640

复现器利用 Apache Polaris Iceberg REST 在位置验证之前发放凭证的漏洞,证明存在跨租户云读取和桶存在性预言问题。

查看仓库
13天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-64640 — Apache Polaris:register 中在位置验证之前发放凭证

这是一个自包含、单命令的 CVE-2026-64640 复现工具:Apache Polaris 中的 Iceberg REST register 端点会为调用者提供的路径发放云存储凭证,并在根据目录的 allowedLocations 检查该路径之前,于服务端读取该路径。

一个仅拥有在其自身目录中创建表权限的主体,可以迫使 Polaris 使用该目录的存储凭证,去读取该目录本不允许接触的对象——另一个租户的前缀、另一个存储桶,以及存储主体能够访问到的任何内容。

CVECVE-2026-64640
组件polaris-runtime-service — IcebergCatalog / LocalIcebergCatalog:registerTable、registerView
端点POST /api/catalog/v1/{prefix}/namespaces/{namespace}/register
POST /api/catalog/v1/{prefix}/namespaces/{namespace}/register-view(1.6.0+)
CWECWE-441(混淆代理)、CWE-639(通过用户控制的键绕过授权)、CWE-918(SSRF)
严重性高——CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N(8.1)
受影响版本≤ 1.6.0(已在 1.3.0-incubating、1.4.0、1.4.1、1.5.0、1.6.0 上验证)
修复版本1.7.0 ——1.6.0 仅修复了表路径,并在新的视图路径上重新引入了该缺陷
所需权限任意目录上具有 TABLE_CREATE / CATALOG_MANAGE_CONTENT 权限的单个已认证主体——无需管理员

1.6.0 并非修复。 它关闭了 register(附带地,在一个功能 PR 内),并发布了带有同样顺序错误的全新 register-view 端点。该复现工具证明了这两个部分。请升级到 1.7.0。

运行

要求:安装了 Compose v2 插件的 Docker、curl、python3、bash。除此之外不需要其他任何东西——环境基于已发布的镜像构建,并在结束后拆除。

root@kitploit:~
./exploit.sh                 # default: apache/polaris:1.4.1  -> reproduces via register
./exploit.sh --tag 1.6.0     # partially fixed               -> reproduces via register-view
./exploit.sh --tag 1.7.0     # comprehensively fixed         -> refuses cleanly on both
./scripts/version-matrix.sh  # every release, side by side

退出码 0 表示漏洞成功复现,1 表示未复现,2 表示环境未能启动。所有请求和响应都会写入 evidence/<timestamp>-polaris-<tag>/。

环境结构

root@kitploit:~
  catalog  tenant_a_catalog        allowedLocations = [ s3://bucket123 ]
  actor    low_priv_user           CATALOG_MANAGE_CONTENT on that catalog, nothing else
  target   s3://tenant-b-private   another tenant's bucket:
                                     no allowedLocations entry, no grant, no relation
                                     to the attacker's catalog — but reachable by the
                                     credentials that back it

最后一行是实际场景中的关键。运维人员使用 allowedLocations 限定目录范围;底层的 IAM 角色几乎总是比一个前缀更宽。allowedLocations 是那道墙。而这个漏洞绕过了它。

它证明了什么

测试 0——墙是真实存在的。 在 s3://tenant-b-private 中使用显式位置创建表会在读取任何内容之前被拒绝,并返回 403 ForbiddenException。Polaris 完全清楚该位置超出允许范围。

测试 1——register 仍然读取了它。 同一个主体将 register 指向 s3://tenant-b-private/sales/metadata/00007-tenant-b-sales.metadata.json。响应同样是 403——但其中引用了 s3://tenant-b-private/warehouse/CANARY-64640-4f1c9e2a-tenant-b-sales,这个字符串仅存在于该对象的内容中:

root@kitploit:~
{"error":{"message":"Invalid locations '[s3://tenant-b-private/warehouse/sales/data,
s3://tenant-b-private/warehouse/CANARY-64640-4f1c9e2a-tenant-b-sales]' for identifier
'tenant_a_ns.pwn_canary': s3://tenant-b-private/warehouse/sales/data is not in the list
of allowed locations: [s3://bucket123/tenant_a_ns]","type":"ForbiddenException","code":403}}

请求从未提及 warehouse/。Polaris 只能通过使用目录的凭证获取并解析该对象来生成这些字符串。这个 403 表明 Polaris 在读取发生之后(而该读取本应被阻止)才捕获到违规。

测试 2——返回了什么。 从受害者文档中解析出的两个不同字段会被回显给调用者:表声明的 location 和它的 write.data.path 属性。

测试 3——存储枚举预言机。 对于 allowedLocations 之外目标的各种状态,同一个调用会给出不同的应答:

四个可区分的应答意味着调用者无权了解的关于存储的四类事实。在真实的 AWS 上,存储桶存在性探测会使用目录的凭证触及全局 S3 存储桶命名空间。

在已修复的构建版本上,该表格中的每一行都是相同的 403,且只指名请求的路径,对象内部的内容不会返回——脚本会检测到这一特征,并报告 NOT VULNERABLE — pre-validation observed。

测试 4——register-view 上的相同缺陷。 Polaris 1.6.0 新增了 POST .../namespaces/{ns}/register-view,进入 registerView,后者加载 FileIO 并在没有任何事先验证的情况下解析调用者的文档——这正是 registerTable 刚刚停止做的事情。在 1.6.0 上,视图金丝雀返回:

root@kitploit:~
{"error":{"message":"Invalid locations '[s3://tenant-b-private/warehouse/CANARY-64640-VIEW-8d3b7a15-tenant-b]'
for identifier 'tenant_a_ns.pwn_view': … is not in the list of allowed locations:
[s3://bucket123/tenant_a_ns]","type":"ForbiddenException","code":403}}

因此,1.6.0 部署仍然暴露于相同的原语,只不过是通过不同的端点。在 1.4.1 及更早版本中,该端点不存在,脚本也会如实说明。

根因

IcebergCatalog.registerTable(自 1.6.0 起为 LocalIcebergCatalog),在修复之前——registerView 具有相同的结构:

root@kitploit:~
String locationDir = metadataFileLocation.substring(0, lastSlashIndex);   // attacker-controlled
...
FileIO fileIO =
    loadFileIOForTableLike(
        identifier,
        Set.of(locationDir),                                              // credentials minted here
        resolvedParent,
        new HashMap<>(tableDefaultProperties),
        Set.of(PolarisStorageActions.READ, PolarisStorageActions.LIST));

InputFile metadataFile = fileIO.newInputFile(metadataFileLocation);       // server-side GET
TableMetadata metadata = TableMetadataParser.read(metadataFile);          // server-side parse
ops.commit(null, metadata);                                               // allowedLocations checked HERE

凭证发放链路(loadFileIOForTableLike → StorageAccessConfigProvider.getStorageAccessConfig → *StorageIntegration.getSubscopedCreds)本身不执行任何 allowedLocations 检查,因此唯一的强制性检查发生在提交(commit)时——而到那时,特权读取已经发生,其结果已经包含在响应中。

同一文件中的同类路径则顺序正确:视图创建和 sendNotificationForTableLike 都在加载 FileIO 之前进行验证。registerTable 是那个不一致的路径。完整分析见 docs/ANALYSIS.md。

修复,包含两部分

表路径——提交 1dd5feeb(2026-06-02,首次发布于 1.6.0)在正确的位置添加了一行:

root@kitploit:~
validateLocationForTableLike(identifier, metadataFileLocation, resolvedParent);

FileIO fileIO = loadFileIOForTableLike(identifier, Set.of(locationDir), ...);

该修复包含在一个功能 PR(“add RegisterTable overwrite support”)中,而非安全修复,因此 1.6.0 在发布该修正时没有附带任何提及它的安全公告。

视图路径——提交 7e822f23(“Validate locations when registering tables and views”,#5114),2026-07-20,首次发布于 1.7.0,为 registerView 添加了相同的防护,并整合了两条路径的解析后检查。

1.7.0 还包含了 85a0c292(#4860,“Fix native catalog credential vending skipping allowedLocations re-validation”),它填补了相关的纵深防御缺口:凭证路径本身现在会重新验证,而不是信任每个调用者。这是问题的结构性一半,也是应该使用 1.7.0 而不是 1.6.0 的另一个原因。

已对照发布标签检查了包含情况:1dd5feeb 位于 1.6.0 和 1.7.0 中;7e822f23 和 85a0c292 仅位于 1.7.0 中。

对于仍处于较旧版本线的人,这两个更改都以补丁形式提供:0001 适用于 ≤ 1.5.0 的表路径,0002 适用于 1.6.0 的视图路径。

运维人员指南——升级路径、缓解措施以及如何在现有日志中查找利用迹象——见 docs/REMEDIATION.md。

已验证的版本矩阵

由 ./scripts/version-matrix.sh 生成;每一行都是一次完整的服务栈启动和一次真实的漏洞利用尝试。参见 docs/AFFECTED-VERSIONS.md。

1.4.1 很关键:它修复了 CVE-2026-42809,即 stage-create 路径中同样的“先发放后验证”错误。该修复仅限于报告中的端点,随后该模式又重复了两次——register 一直保留该行为直到 1.6.0,而 1.6.0 新增的 register-view 从诞生起就带有该问题。

影响范围与客观说明

本复现工具所证明的,仅此而已:

  • Polaris 会对攻击者任意选择的位置执行一次凭证发放后的服务端读取,且该位置位于目录声明的存储边界之外——在 ≤ 1.5.0 上通过 register,在 1.6.0 上通过 register-view。
  • 从该对象中解析出的位置类字段会返回给调用者。
  • 对象存在性、存储桶存在性和对象类型,在目录存储主体可触及的一切范围内都是可观测的。

它没有证明的是:通过 API 批量获取越界对象的完整内容。后续的两项检查(元数据位置必须位于表位置之下,且解析出的位置必须在 allowedLocations 中)会阻止注册完成,因此调用者得到的是一个预言机加元数据片段,而不是完整文档。如果在目录上配置了 S3 端点覆盖,同样的原语就会变成针对所配置主机的服务端请求伪造(SSRF)。

安全性

一切都在本地运行:一个运行在回环端口上的 Docker Compose 项目、一个一次性的 S3(RustFS)实例,以及本仓库自行植入的合成“受害者”文件。不会联系任何外部主机,凭证不会离开机器,并且除非传入 --keep,退出时会运行 docker compose down -v。victim-data/ 中的对象均为伪造;此处没有任何真实数据。

请仅在你拥有或经授权测试的系统上使用。

致谢与披露

在审查 CVE-2026-42809 修复期间发现,通过项目 SECURITY.md 中所述的流程报告给 Apache 软件基金会安全团队,并跟踪为 CVE-2026-64640。

许可证

Apache License 2.0——参见 LICENSE。Compose 环境源自 Apache Polaris 快速入门;参见 NOTICE。

下载工具
探测条件(均在 allowedLocations 之外)1.4.1 响应
有效的 Iceberg 元数据,存在403 ForbiddenException + 回显解析出的位置
键不存在400 NotFoundException — Location does not exist: …
存储桶不存在400 NoSuchBucketException — 原始 S3 SDK 错误
存在但不是 Iceberg 元数据503 RuntimeIOException — Failed to read file: …
版本register(表)register-view结论
1.3.0-incubating存在漏洞端点不存在存在漏洞
1.4.0存在漏洞端点不存在存在漏洞
1.4.1存在漏洞端点不存在存在漏洞
1.5.0存在漏洞端点不存在存在漏洞
1.6.0发放前已验证存在漏洞存在漏洞
1.7.0发放前已验证发放前已验证已修复