从 worse_query 看 iOS 沙盒逃逸:路径、授权与信任边界

· 2026-11-11 12:46 · 1 阅读

原创 jishuzhain 2026-11-11 12:46 广东

— ◆ —

最近,我花了一些时间研究 iOS 上的 worse_query。

最初吸引我的是一个很直接的问题:一个正常运行在 iOS 沙盒中的应用,为什么能够访问其他应用的数据容器?

继续研究之后,我发现这件事情比想象中更有意思。它涉及应用沙盒、App Group、符号链接、Sandbox Extension、文件系统对象身份,以及容器发现技术。单独看,这些都是操作系统和文件系统中并不陌生的概念;但当它们组合在一起时,却可能产生超出系统原本授权范围的访问能力。

我逐渐意识到,真正值得研究的并不只是某个漏洞能够读取哪些文件,而是:

一个应用为什么能够利用操作系统提供的合法授权机制,获得原本不应该拥有的文件访问能力?

这背后涉及一个更基础的安全问题:我们究竟应该信任路径名称、系统服务,还是经过验证的文件系统对象?

本文尝试从安全模型开始,逐步分析 worse_query的技术原理、相关项目的演变、潜在工程原因、修复思路,以及它所揭示的系统信任边界问题。

需要说明,本文依据公开 PoC、项目 README 和第三方技术分析展开。研究者公布的测试结果不等于 Apple 官方确认的受影响范围;理论上的攻击后果也不代表现实中已经发生相应攻击。对于尚未得到充分证实的内部实现细节,我会明确区分事实与推测。

• • •

01

一、为什么手机上的应用不能随意访问彼此的数据?

先从一个非常普通的场景开始。

一台 iPhone 上可能安装了微信、支付宝、银行应用、密码管理器和各种办公软件。它们都运行在同一台设备上,也共享同一个操作系统。

假设某个应用存在恶意代码,或者开发者本身就不可信,我们显然不希望它能够随意读取其他应用的数据。

因此,现代移动操作系统会通过应用沙盒(Sandbox)建立进程之间的隔离边界。

以 iOS 为例,每个应用通常拥有自己的数据容器,用来保存应用文档、缓存、数据库、配置文件和其他运行数据。

可以将其简化为:

应用数据容器 │ ├── App A │   ├── Documents │   ├── Library │   └── tmp │ ├── App B │   ├── Documents │   ├── Library │   └── tmp │ └── App C     ├── Documents     ├── Library     └── tmp

应用 A 正常情况下不能直接访问应用 B 的私有数据,应用 C 也不能随意修改应用 A 的数据库。

这是一种典型的最小权限设计:应用只获得完成自身任务所需要的资源访问能力。

但是,现实中的软件系统不会永远保持如此简单。

应用之间可能需要共享文件,同一开发者的多个应用可能需要访问共同的数据库,主应用也可能需要与扩展程序交换数据。

因此,iOS 提供了 App Group 等共享机制。

App Group 允许具有相应 entitlement 的应用共享指定的数据容器。它是经过系统授权的例外,而不是对沙盒隔离原则的废除。

问题也由此变得复杂:系统既要允许合法共享,又必须确保应用不能利用共享机制访问其他应用的私有容器。

• • •

02

二、Sandbox Extension:合法授权机制也可能成为攻击入口

理解 worse_query,还需要认识另一个概念:Sandbox Extension。

沙盒并不是只能在应用启动时确定一次权限。在某些业务场景下,应用需要动态获得额外的资源访问能力。

Sandbox Extension 可以理解为一种动态授权凭证。系统在满足条件时签发令牌,应用再消费令牌,从而获得特定资源的额外访问权限。

简化表示:

T= Grant(P, R)

其中:

—P:申请访问的进程。

—R:请求访问的资源。

—T:系统签发的授权令牌。

正常情况下,系统应当保证最终授权的资源不超过申请主体被允许访问的范围。

这里有一个关键问题:

系统如何确认请求的资源究竟是什么?

假设应用申请访问:

AppGroup-A/Library/Caches

系统需要判断这个目录是否属于 App Group A,以及申请者是否有权访问它。

如果系统只根据路径名称进行判断,却没有正确处理路径解析过程中出现的符号链接,就可能出现问题。

这正是公开 worse_query研究所展示的核心方向。

• • •

03

三、符号链接:路径名称不等于文件系统对象

符号链接(Symbolic Link)是文件系统提供的一种机制。

它允许一个路径指向另一个文件或目录。

例如:

AppGroup-A/Library/Caches               |               └── Symbolic Link                        |                        v                 App-B/Documents

从路径名称看,请求似乎仍然发生在 App Group A 的目录结构之内。

但当系统解析符号链接后,最终访问的对象可能已经位于 App B 的私有容器。

这里存在一个容易被忽略的区别:

—路径(Path)是定位资源的名称。

—文件系统对象(Filesystem Object)才是实际被访问的对象。

路径与对象之间并不是始终固定的一一对应关系。

如果授权服务只验证原始路径是否位于授权容器,却没有在符号链接解析后重新验证最终对象的归属,就可能出现授权边界错误。

可以用一个简化模型表达:

Prequest∈ CA

但是:

Resolve(Prequest) = OB

其中,CA是 App Group A 的授权容器,OB则是解析后位于 App B 容器中的文件系统对象。

如果系统只验证第一条,而没有可靠验证第二条,就可能错误地为外部对象授予访问权限。

这也是理解 worse_query最重要的切入点:

系统预期授权的资源,与路径解析后实际指向的资源可能发生偏离。

Ostorlab 对公开 PoC 的技术分析,以及相关研究者公布的实现,都指向了这一类容器查询和符号链接处理问题。

但需要注意,我们能够从公开材料中确认的是利用行为及其表现,不能据此声称已经完整掌握 Apple 内部所有相关函数的实现细节。

• • •

04

四、从 bad_query 到 worse_query:修复一种输入,不代表修复整个边界

研究过程中,我还发现了一个有意思的技术演变过程。

bad_query是较早公开的 iOS 沙盒逃逸 PoC。其 README 声称适用范围为 iOS 26.0–26.6.1 和 iOS 27.0 beta 4。

后续的 worse_query是它的直接继任者。项目 README 声称适用于 iOS 26.0–26.7.2 和 iOS 27.2,并要求运行应用配置 App Group 容器。

两者并不是简单的版本升级,而是展示了不同的利用路径。

根据 KAMUI 作者对 iOS 27.2 的技术分析,早期 bad_query的一条路径利用了路径参数中的 ..,试图改变容器查询的目标。

在 iOS 27.2 上,相关路径遍历受到限制:系统会拒绝包含 ..的相关参数,并对部分非空路径域进行符号链接解析和边界检查。

但是,研究者进一步发现,另一条路径仍然值得关注:在特定查询条件下,系统对 part 目录本身的边界验证可能不完整。

于是,问题不再只是路径字符串中有没有 ..,而是系统在处理应用可控制的目录结构时,是否始终验证最终解析对象仍属于预期容器。

这两种利用方式有一个共同的安全问题:系统授权流程中的路径解析与容器边界验证。

但不能仅凭公开 PoC 就断言它们对应完全相同的内部代码缺陷。

这里有一个很值得记住的安全工程结论:

修复一种已知攻击输入,与证明整个授权模型不存在同类缺陷,是两件完全不同的事情。

如果系统只过滤一种路径遍历形式,却没有保证所有路径解析分支都遵守相同的授权边界,那么它可能只是堵住了一条路,而不是修复了整个安全问题。

• • •

05

五、为什么会出现这样的漏洞?

目前公开材料足以帮助我们理解利用行为,但不足以完整还原 Apple 内部的设计决策和开发过程。

因此,与其直接断言某个程序员漏写了一次检查,不如从安全工程角度分析可能存在的问题。

1. 路径校验与路径解析没有形成完整闭环

系统需要判断某个资源是否位于授权容器中。

如果检查对象只是未经解析的路径字符串,那么符号链接就可能改变最终访问对象。

这意味着:

Authorized(P) ⇏ Authorized(Resolve(P))

原始路径合法,并不意味着解析后的对象也合法。

2. 过度信任应用可以控制的目录结构

应用可以控制自己容器中的部分文件系统结构,例如创建、删除或替换目录项。

因此,系统不能简单地假设某个应用容器内部的目录结构始终可信。

特别是在授权流程中,应用可控的目录项应当被视为不可信输入。

3. 路径检查与实际访问可能存在时间差

这会让人联想到 TOCTOU(Time Of Check to Time Of Use)。

假设系统先检查某个路径是否合法,随后才真正打开文件。如果两次操作之间路径指向的对象发生变化,就可能出现检查对象和使用对象不一致的情况。

但这里需要保持严谨:公开的 worse_query分析主要展示了符号链接造成的授权边界问题。不能仅凭这个现象,就把整个漏洞归类为经典 TOCTOU。

是否存在竞态、竞态是否是必要条件,需要结合具体实现和实验进一步验证。

4. 系统接口组合增加了安全审计难度

容器管理、应用共享、路径查询和动态授权,并不是彼此完全独立的功能。

它们共同组成了一个复杂的系统服务链条。

某个接口单独运行时可能没有问题,但当它与其他接口组合后,就可能产生新的安全边界。

这也是复杂操作系统中比较典型的安全风险:单个组件的设计假设,在跨组件调用时不再成立。

• • •

06

六、从根本上解决,应该修复什么?

如果只把修复方案总结为“禁止符号链接”,我认为是不够的。

符号链接本身是文件系统的正常功能。真正需要保证的是:系统在授权时,必须确认最终访问对象确实属于被授权的资源范围。

假设容器根目录为 C,最终解析得到的对象为 O。

系统需要验证:

O∈ C

而且不能仅仅依靠字符串前缀比较。

例如:

/containers/App-A /containers/App-A-evil

第二个路径也以第一个路径开头,但它显然不是 App A 的容器。

更可靠的设计需要考虑:

1.对路径进行安全解析,识别符号链接。

2.验证最终对象与授权容器之间的真实目录关系。

3.在检查和使用之间保持对象身份一致。

4.防止目录替换和其他竞态条件。

5.确保 Sandbox Extension 的授权范围不能超过原始授权范围。

在 POSIX 系统中,可以研究 openat()、目录文件描述符、O_NOFOLLOW等机制。

这些技术有助于降低路径解析中的风险,但不能简单地认为使用其中某个系统调用就能解决所有问题。多级符号链接、目录替换、文件系统挂载和并发操作仍然需要综合处理。

还有一个容易被忽视的方面:即使操作系统沙盒发生失效,应用本身也应该对敏感数据进行保护。

例如:

—对敏感数据进行加密存储。

—将密钥与业务数据分离。

—使用 Keychain 管理适当的凭据。

—对高价值密钥考虑 Secure Enclave 支持的保护机制。

—为会话凭据设计有效期、撤销和设备绑定机制。

—对敏感操作增加服务端验证。

沙盒解决的是谁可以访问文件,加密解决的是即使文件被访问,攻击者是否能够理解其中的数据。

二者不是替代关系,而是不同层次的纵深防御。

• • •

07

七、知道资源在哪里,不代表有权访问:fsgetpath 与容器发现

研究 worse_query时,还有一个值得单独讨论的技术问题:攻击者如何知道其他应用的容器在哪里?

这涉及 fsgetpath()。

文件系统中的文件或目录具有相应的对象标识。对于 APFS 等文件系统,相关实现中会涉及 inode 和文件系统标识等信息。

fsgetpath()可以在满足系统条件时,根据文件系统标识和 inode 等信息反查路径。

可以把它简化为:

(Filesystem ID, Inode) ⟶ Path

这与通常的路径查找方向不同。

通常我们是:

Path ⟶ Filesystem Object

而这里讨论的是从文件系统对象标识反查路径。

worse_query仓库中包含一个名为 pathleak的辅助实现。其源码说明展示了通过 inode 遍历并调用 fsgetpath()获取路径的思路。

这类实现的意义,是帮助研究者发现目标路径,而不是直接授予文件访问权限。

还需要区分另一个项目:KAMUI。

KAMUI 是一套独立的 iOS 容器级沙盒逃逸实现,而不只是路径枚举工具。它也使用 fsgetpath()等方式发现容器路径,但其核心研究目标同样包括获取超出自身容器范围的访问能力。

KAMUI 作者公布的测试结果声称,在其测试环境中,正常沙盒进程能够取得特定外部容器的读写 Sandbox Extension。作者同时强调,这不是 root 权限,也不是内核漏洞,更不是完整的文件系统逃逸。

WQ Files 则明确将 worse_query作为沙盒访问技术来源,将 KAMUI 作为 fsgetpath()容器枚举思路的来源。

WQ Files 的说明还提到,在某些系统版本和目录条件下,工具会结合 LaunchServices 数据库获取应用及扩展容器信息;元数据不足时,再使用 inode 扫描等方式。

这说明实际工具可能采用多种数据来源,而不是简单地遍历整个文件系统。

从工程角度看,这是一种常见的设计:已有元数据能够解决的问题,就不必重新扫描;元数据不完整时,再使用成本更高的发现机制。

但必须再次强调:

路径发现、权限授权和文件操作,是三个独立的问题。

知道一个应用的容器路径,不代表拥有访问权限;获得某种文件访问能力,也不代表能够读取其中所有受保护的数据。

• • •

08

八、从漏洞 PoC 到工具:能力组合改变了什么?

单独研究一个漏洞,通常关注的是:

—利用条件是什么?

—哪个安全边界被突破?

—能访问哪些资源?

—系统是否已经修复?

但当漏洞能力被整合进一个可操作工具时,安全影响的讨论范围就会扩大。

以 WQ Files 为例,它将文件访问能力与文件浏览、编辑、备份、恢复和清理等功能结合起来。

这意味着研究者不再只是验证一个授权错误,而是能够通过工具界面观察和操作目标数据。

从安全分析角度,可以把相关能力拆成三个阶段:

阶段

解决的问题

Discovery

目标容器在哪里?

Authorization

当前进程是否有权访问?

Operation

实际能够读取、修改或删除什么?

这三个阶段组合后,才形成相对完整的数据访问能力。

这里也体现出一个很重要的安全研究方法:

不要只盯着单个漏洞,而应该分析不同系统能力组合之后,是否产生了设计者没有预料到的安全后果。

一个漏洞负责突破权限边界,另一种技术负责发现目标路径,文件管理能力负责执行后续操作。

它们各自解决的问题不同,但组合后可能形成更完整的能力链。

这并不是说所有攻击者都已经拥有这样的能力,也不是说所有设备都能被同样操作。实际影响还受到系统版本、设备状态、文件保护类别、应用数据加密方式和利用条件等因素限制。

• • •

09

九、哪些人群需要关注?

漏洞风险不能只看技术上能做什么,还要考虑目标数据的价值、攻击者接触设备的机会以及实际利用条件。

1. 数字资产持有者

对于手机钱包用户,值得关注的数据包括钱包数据库、身份凭据、会话信息和可能存在的密钥材料。

但不能把读取钱包目录直接等同于获取私钥。

密钥是否加密、是否受到 Keychain 访问控制保护、是否依赖 Secure Enclave,以及设备当前锁定状态,都会影响最终结果。

2. 企业和政企工作人员

手机已经成为重要的办公终端。

企业应用可能存储客户资料、内部文档、业务配置、身份凭据和工作记录。

如果这些数据仅仅依赖应用沙盒保护,那么沙盒边界失效就会成为需要重新评估的风险。

3. 应用开发者和互联网企业

开发者需要重新审视客户端的数据安全设计。

特别是那些在本地保存大量业务状态、用户信息和认证凭据的应用。

操作系统提供沙盒,不代表应用可以完全放弃自身的数据保护。

4. 安全研究人员和移动安全团队

这类人群需要关注漏洞的真实影响范围、复现条件、修复状态和检测能力。

尤其要区分:

—PoC 能够证明什么。

—工具实际实现了什么。

—真实攻击需要哪些额外条件。

—哪些安全机制仍然有效。

5. 普通用户

普通用户不必因为看到沙盒逃逸就认为自己的手机已经被远程控制。

公开研究展示的主要是本地应用触发的利用路径,并不等于攻击者只需要知道手机号、IP 地址或 Apple ID,就能远程读取 iPhone 数据。

真正需要关注的是设备上运行了什么应用、应用来源是否可信,以及系统是否处于受影响状态。

• • •

10

十、如果攻击者利用它,可能造成什么后果?

现在可以从攻击者视角进行风险推演,但必须把理论能力和已经发生的事件区分开。

一个可能的数据访问场景,可以抽象为:

恶意或不可信应用运行         |         v 利用系统授权边界缺陷         |         v 获得超出预期的文件访问能力         |         v 发现目标应用容器         |         v 识别具有价值的数据         |         v 尝试读取、复制或修改数据         |         v 在满足额外条件时造成后续影响

可能的影响包括:

攻击目的

潜在后果

信息收集

接触本地文档、数据库和缓存

凭据窃取

尝试获取暴露的会话信息或认证材料

隐私泄露

获取个人记录和应用数据

数据破坏

修改或删除其他应用的本地数据

后续攻击

利用获取的信息尝试账户接管或其他攻击

需要注意,读取到文件不代表一定能够解密;获得数据不代表一定能够完成账户接管;能够访问本地容器也不代表能够突破设备的所有安全机制。

特别是对于钱包私钥、银行凭据和其他高价值信息,实际风险取决于它们的存储与保护方式。

截至本文核查时,公开项目和技术分析展示了相关沙盒逃逸及文件管理能力,但没有足够证据证明已经发生大规模数据窃取或针对竞争企业的商业间谍活动。

风险推演不能替代事件证据。

• • •

11

十一、漏洞是否已经修复?

这是研究中不能回避的问题。

截至 2026 年 11 月 11 日,worse_query项目 README 声称的测试范围为 iOS 26.0–26.7.2 和 iOS 27.2;KAMUI 项目则声称支持 iOS 27.0.1–27.2。

这些都是项目作者公开声明的测试范围,不是 Apple 官方确认的完整受影响版本列表。

Apple 于 2026 年 11 月 9 日发布了 iOS 27.2.1 和 iOS 26.7.3 安全更新。

我核对了这两个版本的官方安全公告,其中列出了 AirPlay、App Intents、Bluetooth、CoreUtils、Messages、rapportd 等安全问题,但没有明确列出 worse_query所涉及的 MCM 容器管理或沙盒逃逸问题。

这只能说明:在目前公开的安全公告中,没有找到明确对应的修复说明。

不能反过来断言 Apple 一定没有修复。安全公告没有提及某个问题,并不构成对其修复状态的绝对证明。

此外,WQ Files 最新发布说明明确标注了 iOS 27.0.1 的测试环境,并说明其他 iOS 27 版本尚未测试。因此,不能把工具作者的版本兼容性推测当作已经验证的结果。

对普通用户而言,保持系统更新仍然是合理的安全建议。对研究人员而言,则应当等待对应系统版本的独立验证,不能仅凭版本号或公告缺失下结论。

• • •

12

十二、真正值得思考的,是我们究竟信任什么

回到最初的问题。

用户信任应用,应用依赖操作系统,操作系统依赖系统服务和内核安全机制。

这是一条层层依赖的信任链。

用户  │  │ 信任应用保护个人数据  ▼ 应用  │  │ 信任操作系统提供隔离  ▼ 系统服务  │  │ 管理容器与动态授权  ▼ 内核安全机制  │  ▼ 文件系统与访问控制

如果其中某个组件出现错误,其他组件是否能够限制它造成的损害?

这才是纵深防御和最小权限真正需要回答的问题。

我们习惯把操作系统沙盒当成一种可靠的保护机制,但安全工程不应该建立在“某个组件永远不会出错”的假设之上。

更合理的设计是:即使一个组件发生故障,其他组件仍然能够限制影响范围。

例如,授权服务不应该因为一个路径看起来属于某个容器,就直接相信它;应用也不应该因为操作系统提供了沙盒,就把所有重要数据以明文形式保存在本地。

安全不是单个组件的承诺,而是一组相互约束的机制。

worse_query让我们看到,路径名称、文件系统对象和授权范围之间的细微差异,可能成为安全边界失效的入口。

而 pathleak、KAMUI 和 WQ Files 又让我们看到,漏洞利用、目标发现和文件操作能力组合起来之后,可能产生比单个 PoC 更完整的影响。

这也是我认为这个研究案例值得关注的原因。

它并不只是一个 iOS 漏洞,而是一个关于操作系统权限模型、文件系统安全和信任边界的具体案例。

我们真正需要信任的,不是某个组件永远正确,而是整个系统在某个组件不正确时,仍然能够保护住最重要的边界。

• • •

参考资料

以下优先列出原始项目和官方资料,便于读者自行核对。项目作者公布的测试结果与技术判断,应当理解为项目方的研究声明,而非 Apple 官方结论。

1.forcequitOS / bad_query —— 早期 iOS 沙盒逃逸 PoC。

2.forcequitOS / worse_query —— 后继 PoC,包含版本声明及相关辅助实现。

3.murk-sus / KAMUI —— 独立的 iOS 容器级沙盒逃逸研究及相关工具。

4.kolbicz / WQFiles —— 基于 worse_query 的文件浏览、应用数据管理工具。

5.Ostorlab 技术分析 —— 第三方移动安全研究资料。

6.Apple:About the security content of iOS 27.2.1 and iPadOS 27.2.1 —— 2026 年 11 月 9 日官方安全公告。

7.Apple:About the security content of iOS 26.7.3 and iPadOS 26.7.3 —— 2026 年 11 月 9 日官方安全公告。

研究说明:本文讨论的是公开研究材料所展示的技术行为和安全设计问题,不构成对所有 iOS 设备受影响状态的判断。具体版本适用性、漏洞修复情况及现实攻击事件,应以 Apple 官方披露和独立复现结果为准。

跳转微信打开

本文转载自微信公众号「OnionSec」,查看原文。版权归原作者所有,如有侵权请联系删除。