worse_query iOS sandbox escape: how the unpatched zero-day Escapes iOS Sandbox

The CyberSec Guru

worse_query iOS sandbox escape

If you like this post, then please share it:

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Why your support matters: Zero paywalls: Keep the main content 100% free for learners worldwide.

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

Between Sunday, November 8, and Tuesday, November 10, 2026, a GitHub repository from independent iOS researcher forcequitOS (Taj) and contributor @0xjohnny went from a niche proof of concept to the subject of a cryptocurrency security advisory. The technique, called worse_query, is a zero-day application sandbox escape affecting iOS 26 and iOS 27.

Within 48 hours of the code going public, developer Christoph Kolbicz (_kolbicz) had built it into WQ Files, a non-jailbreak file manager that can browse, back up, and modify other apps’ data containers. By Tuesday morning, Binance had issued an urgent alert. A malicious host app on iOS 26.7.1, 27.0.1, or 27.2 can cross container boundaries and read local files belonging to other installed apps, including unencrypted seed phrases, private keys, browser caches, and session tokens.

worse_query does not break the XNU kernel or disable hardware-enforced code signing. It is an unpatched userland containment failure, and it works through the interaction between iOS container management queries, App Group entitlements, and inode-to-path resolution via the fsgetpath system call.

The release timeline adds to the problem. forcequitOS published the proof of concept on Sunday, November 8, citing slow vendor communication and rumors that third parties were already experimenting with the bug. On Monday, November 9, Apple shipped iOS 27.2.1 and iOS 26.7.3. Those updates fixed two iMessage privacy issues and several Bluetooth pairing bugs and left worse_query untouched. The researcher confirmed the gap exists in both iOS 27.2.1 and iOS 27.3 beta 1.

What is worse_query?

worse_query is an Objective-C sandbox escape for iOS 26 and 27, written as the direct successor to forcequitOS’s C-based bad_query proof of concept from August 2026. bad_query showed that malformed or manipulated container queries could trick the system into granting unintended access on early iOS 26 and 27 builds. worse_query refines that primitive so an unprivileged process can reach across container boundaries that should be opaque to it. That includes other apps’ data containers, extension containers, App Groups, and on iOS 27, SystemGroup paths such as the container holding com.apple.mobilegestalt.plist. That last capability quickly revived utilities like GestaltX.

How worse_query works: container queries, fsgetpath, and VFS traversal

How iOS app sandboxing normally works

Isolation on modern iOS is enforced by the AppleMobileFileIntegrity (AMFI) kext and the Sandbox.kext extension (historically Seatbelt), working with userland daemons such as containermanagerd and installd. When you install an app, the system creates UUID-randomized directories on the data volume. The signed, read-only bundle lives at /var/containers/Bundle/Application/<UUID>/, and the mutable runtime data lives at /var/mobile/Containers/Data/Application/<UUID>/. Shared group containers sit under /var/mobile/Containers/Shared/AppGroup/<UUID>/ and system group containers under /var/containers/Shared/SystemGroup/<UUID>/.

A third-party app normally runs under a strict container sandbox profile that hooks VFS operations at the Mandatory Access Control (MAC) layer in XNU. If App A calls open(), stat(), or opendir() on /var/mobile/Containers/Data/Application/, or guesses the 128-bit UUID of App B’s data directory, the kernel’s MAC hook intercepts the vnode lookup and returns EPERM or ENOENT.

Apps also don’t hardcode container paths. They go through system APIs (NSFileManager, libsystem_containermanager.dylib) that talk over XPC to containermanagerd to look up or provision paths and to acquire sandbox extension tokens. A sandbox extension is a signed capability token issued by a privileged daemon. The client process consumes it, and can later release it with stopAccessingSecurityScopedResource, to widen its sandbox profile for one filesystem subtree.

How worse_query breaks container isolation

worse_query abuses query handling inside this container resolution machinery. An unprivileged process ends up with read and write reach across containers that it should never see.

That alone is only half of what an attacker needs. Even with the logical boundary weakened, an app can’t simply call opendir("/var/mobile/Containers/Data/Application") and loop through readdir() to find the UUID folders of installed crypto wallets. On iOS 27.0.1, as documented in Kolbicz’s WQ Files project, the parent directories that hold app containers don’t hand out sandbox tokens for enumeration. Listing them fails because the process lacks read permission on the parent vnode, even though the flaw lets it open child paths once their exact names are known.

📬 Stay Ahead of Cyber Threats

Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.

To close that gap without a kernel memory-corruption primitive, worse_query and the tools built on it combine two userland techniques: database extraction and kernel inode-to-path resolution.

Why fsgetpath solves the directory enumeration problem

On iOS 26 builds (iOS 26.0 through 26.7.2), WQ Files first queries the LaunchServices database (com.apple.LaunchServices-*.csstore). LaunchServices keeps the registry of installed bundle identifiers, plugins, App Groups, and their UUID container paths so it can broker URL schemes and document opening. Reading it hands the attacker a map of user-installed apps, extensions, and shared App Group paths right away. It does not index internal system daemons or unindexed subdirectories, though, and on iOS 27.0.1 the container parent directories refuse standard token acquisition.

That is where fsgetpath comes in (SYS_fsgetpath, syscall 427 in Darwin/XNU). It is the same path-resolution primitive publicized in the earlier KAMUI iOS research project and in container explorers like veilpath. Its C signature is:

c

ssize_t fsgetpath(char * restrict buf, size_t buflen, fsid_t * restrict fsid, uint64_t objid);

Normal POSIX traversal starts at / and walks down component by component (var, mobile, Containers, Data, Application, <UUID>), checking search permission at every parent directory. fsgetpath works in reverse. Given a filesystem identifier (fsid_t, usually obtained with statfs() on an accessible mount point such as /var or the app’s own container) and a 64-bit object ID (objid, the APFS catalog node ID), it asks the kernel’s VFS and APFS layers to resolve that inode number back to an absolute path.

APFS assigns sequential or predictable 64-bit inode numbers as files and directories are created. A userland process can therefore count from 0 up to a bounded max_inode (a parameter visible in forcequitOS’s repository history) and pass each number to fsgetpath(). When an inode maps to a valid file or container directory that the current sandbox state doesn’t redact during reverse path construction, the kernel returns the full path, unguessable UUID included. For example: /var/mobile/Containers/Data/Application/8F3A9C12-4B7E-4D1A-9E2C-5108A7B3D4E1/Documents/wallet.sqlite.

Once the path is known, the app never has to enumerate the forbidden parent directory. It pairs the container-query bypass with direct operations on the target child.

The cost is time. The WQ Files developers report that on iOS 26 builds, an exhaustive fsgetpath sweep of the whole APFS inode space takes the better part of an hour, because of the volume of syscalls and APFS B-tree lookups. So the tools use LaunchServices to populate user app containers instantly where they can. They save the heavy inode sweep for internal daemons and for the iOS 27.0.1 parent-directory restrictions, and they cache discovered mappings so later scans only query inode numbers above the previous high-water mark.

Why App Groups decide who is at risk

If worse_query can read arbitrary app containers without a kernel exploit, why hasn’t every flashlight app on the App Store already drained every mobile wallet? Because the exploit chain has a prerequisite: the host app must hold an active App Group entitlement (com.apple.security.application-groups).

App Groups are the legitimate way for apps from the same developer team, or an app and its widget, share extension, or notification service extension, to share a directory outside their individual sandboxes. An app can’t request the entitlement at runtime. It is bound into the Mach-O LC_CODE_SIGNATURE load command as part of the embedded entitlements plist, and it has to match a provisioning profile (.mobileprovision) signed by Apple’s certificate authority. When installd and containermanagerd install the app, they verify the signature through AMFI and build the shared container under /var/mobile/Containers/Shared/AppGroup/<UUID>/.

Since worse_query needs a valid App Group context to start its cross-container query abuse, the risk depends on how the malicious app reaches the device.

Sideloaded and developer-signed IPAs (highest immediate risk)

AltStore, SideStore, Sideloadly, and Xcode’s free Apple ID signing let users install arbitrary .ipa files outside the App Store. When AltStore or SideStore signs an IPA with your Apple ID, it automatically attaches an App Group entitlement to manage its own refresh and pairing state. Anyone who sideloads an unvetted game, tweaked social client, cracked utility, or “cache cleaner” therefore gives that binary exactly the entitlement worse_query needs.

Within hours of the release, developers had packaged full filesystem browsers that install through AltStore or SideStore and expose every app container on the device. These include WQ Files by Kolbicz and FilzaWorse by Torrekie, plus updates to Erosion and GestaltX.

Enterprise certificates and ad-hoc distribution (high risk)

Organizations in the Apple Developer Enterprise Program, and users of abused enterprise certificates on gray-market signing platforms, distribute .ipa files through MDM or web manifests (itms-services://) without going through App Review. Enterprise apps routinely carry com.apple.security.application-groups so corporate suites can share authentication state. A compromised enterprise build, or a trojanized IPA signed with a leaked enterprise certificate, arrives with everything worse_query needs.

The official App Store (unclear, conditional risk)

Neither Binance, forcequitOS, nor the developers of WQ Files and Erosion have said whether a standard App Store app could weaponize worse_query. An app without an App Group entitlement can’t acquire one after installation. But thousands of legitimate App Store apps ship with the entitlement because they bundle home-screen widgets or share extensions.

To exploit worse_query through the App Store, an attacker would have to submit an app with a legitimate App Group (a dummy widget would do) and hide the Objective-C query calls and fsgetpath loops well enough, perhaps through dlsym resolution or server-side flags, to get past Apple’s automated static analysis. No such malware has been observed. The barrier on the App Store is App Review detection, since nothing in the architecture stops App Store binaries from holding the entitlement.

What worse_query can and cannot steal from a crypto wallet

When SlowMist CISO 23pds (Shan) and Binance’s security team analyzed worse_query on November 10, both pointed to the same distinction. worse_query is a filesystem container escape. It is not a Secure Enclave or Keychain decryption primitive. To judge the risk to a wallet, you have to separate what sits in /var/mobile/Containers/Data/Application/<Wallet-UUID>/ from what sits in hardware-backed storage.

iOS separates general app file storage (APFS Data Protection classes) from the Keychain database and the Secure Enclave Processor (SEP). While the phone is unlocked, the APFS keys for ordinary app files are loaded so apps can read and write their own data. Normally App A still can’t read App B’s decrypted files, because the sandbox blocks the access.

worse_query removes that wall while the device is unlocked and the malicious app is running. After crossing into a wallet’s container (Documents/, Library/Application Support/, Library/Caches/, Library/Preferences/, or tmp/), the attacker’s process can read every file in plaintext, because the OS transparently decrypts APFS blocks for any permitted read during the user session.

Data that is exposed

Plaintext or app-level obfuscated seed phrases and keystores. Well-built iOS wallets keep BIP-39 mnemonics and private keys only in the iOS Keychain (/var/Keychains/keychain-2.db), where each item is encrypted with a per-item key wrapped by the Secure Enclave’s hardware UID key (kSecAttrAccessibleWhenUnlockedThisDeviceOnly). Another app can’t read those entries even with a filesystem escape, because Keychain access is gated by the keychain-access-groups entitlement enforced by securityd, not by file paths.

SlowMist’s 23pds pointed out that plenty of multi-platform wallets, especially ones built on React Native, Flutter, Cordova/Capacitor, or WebView wrappers, make serious compromises. Some store JSON keystores, LevelDB or SQLite databases (including IndexedDB under Library/WebKit/WebsiteData/), MMKV stores, or custom .plist files in Documents/ or Library/Application Support/, with no encryption or with a static AES key compiled into the binary. Others forget the NSURLIsExcludedFromBackupKey flag and leave temporary mnemonic backups in tmp/ or Caches/. With worse_query, a malicious app can copy those databases and plists in seconds.

Login sessions, OAuth tokens, and WebView caches. Even when a wallet or exchange app (Binance, Coinbase, Kraken) keeps its signing keys in the Keychain or on a server, it often stores HTTP session cookies (Library/Cookies/Cookies.binarycookies), JWTs, refresh tokens, GraphQL caches, and WKWebView local storage in the container. By reading those files, an attacker can clone an authenticated session without knowing the password or getting past 2FA. That is why Binance paired its wallet-migration warning with an instruction to reset all active login sessions.

Shared App Group data. Many reputable financial and crypto apps use App Group containers to share balances, watchlists, or session state with a home-screen widget or Watch companion. worse_query enumerates and opens App Group containers system-wide, so anything sensitive placed there for a widget can be extracted.

Data that stays protected

Hardware-backed Keychain items and Secure Enclave keys. If a wallet generates an elliptic curve key inside the Secure Enclave (kSecAttrTokenIDSecureEnclave), or stores its BIP-39 entropy strictly in the Keychain through SecItemAdd without writing backups or logs to the container, worse_query can’t extract the key material. It doesn’t break securityd entitlement checks and it doesn’t compromise the Secure Enclave Processor.

worse_query timeline: from bad_query to the unpatched iOS 27.2.1

Reconstructed from GitHub commit histories, Trendshift repository telemetry, and posts on X and Reddit, the window was narrow.

  • August 2026: forcequitOS publishes bad_query, the C-based precursor targeting early iOS 26 and 27 builds. Contributors submit hardening fixes, including pull request on August 11, which addresses max_inode bounds and stopAccessing resource leaks.
  • November 7 to 8, 2026: forcequitOS and @0xjohnny publish the forcequitOS/worse_query repository (“A sandbox escape for iOS 26 and 27, again”). It gains 54 stars on Sunday, November 8, and another 41 on Monday. forcequitOS said on X that they hadn’t planned to release it early: “Apple was stalling on responding to me and people started larping with it on here.” That suggests knowledge of the vector was already leaking into social channels while Apple’s response stalled.
  • November 8 to 9, 2026: forcequitOS described the repository as developer-oriented code that was “not useful by itself,” and the iOS developer community turned it into consumer tools in under a day. Kolbicz launched kolbicz/WQFiles, an Objective-C file browser, app data manager, plist and binary editor, and cache cleaner for iOS 26 and 27 that needs no jailbreak. Torrekie released FilzaWorse, a patched Filza variant adapted to worse_query. GestaltX and Erosion integrated the primitive to modify MobileGestalt and system configuration files in SystemGroup containers.
  • Monday, November 9, 2026: Apple releases iOS 27.2.1 and iOS 26.7.3. The security notes cover two iMessage group chat privacy flaws and several Bluetooth pairing vulnerabilities. They don’t mention worse_query, containermanagerd, fsgetpath, or any sandbox fix. Apple’s policy is not to confirm issues until an investigation and patch are complete, so forcequitOS cleared up the confusion directly: “Just as a general statement so there isn’t any confusion about it, worse_query is not patched in iOS 27.2.1 and 27.3 beta 1. I’ll update version support on the readme when it’s patched.” Erosion’s maintainers added iOS 27.2.1 to their docs with the note “pretty sure 27.2.1 is supported.”
  • Tuesday, November 10, 2026: With installable IPA tools circulating and no OS patch available, Binance and SlowMist publish advisories warning of exposure on iOS 26.7.1, 27.0.1, and 27.2. Those are the three builds verified in the WQ Files release notes, within the researcher’s wider supported range of iOS 26.0 to 26.7.2, iOS 27.0.1 to 27.2.1, and iOS 27.3 beta 1.

How to protect yourself from worse_query

worse_query is unpatched in current production firmware, including iOS 27.2.1, and has no assigned CVE. Nobody can fix it with a software update today. Defense means stopping the malicious app from getting onto the device, cleaning up any credentials that may be exposed, and changing how apps store local state.

For iPhone users and crypto holders

If you keep crypto wallets, authenticator apps, or banking sessions on an iPhone running iOS 26 or 27, your exposure depends on whether an untrusted binary with an App Group entitlement has run on your phone.

  1. Audit and remove sideloaded or enterprise-signed apps. Go to Settings > General > VPN & Device Management and check every entry under “Developer App” or “Enterprise App.” Delete anything installed through AltStore, SideStore, Sideloadly, TrollStore-style tools, third-party app stores, or unverified enterprise certificates, and remove the related provisioning profiles. Without the host app, worse_query has nothing to run from.
  2. Migrate to a clean device if you have run sideloaded apps. If you’ve run sideloaded or manually signed IPAs since early November 2026 alongside a software crypto wallet, assume your app containers were readable. Don’t just create a new wallet in the same app on the same phone. A resident malicious app, or a wallet that caches plaintext locally, exposes the new keys just as it did the old ones. Set up a new wallet (or a hardware wallet) on a separate device that has never hosted sideloaded packages, move your assets on-chain to the new addresses, and retire the old seed phrase for good.
  3. Revoke and rotate login sessions. Because an attacker can copy Cookies.binarycookies, WKWebView storage, and OAuth refresh tokens, changing your password may not be enough if an app doesn’t invalidate old tokens server-side. Log in to your exchange accounts (Binance, Coinbase), cloud storage, and messaging apps (Telegram, Discord) and trigger “Log out of all other devices” or reset active sessions.
  4. Keep iOS updated anyway. iOS 27.2.1 and 26.7.3 don’t fix worse_query, but they do fix the iMessage and Bluetooth issues patched on November 9. Staying current also means your device is ready for whatever out-of-band update Apple ships for the container-query fix, such as a Rapid Security Response or iOS 27.2.2.

For enterprise mobility teams (MDM and EMM)

worse_query runs entirely in userland. A kernel exploit risks a panic log or tripping Kernel Integrity Protection (KTRR/PPL). worse_query uses valid syscalls (fsgetpath) and IPC queries that produce no crash logs. Tools like WQ Files keep an internal log of their file writes, backups, and deletions, but a malicious payload won’t log itself. Three MDM controls help:

  • Block unvetted provisioning profiles. Use profile-installation restrictions in supervised MDM configurations, including allowUntrustedTLSPrompt, so users can’t trust ad-hoc developer Apple IDs or third-party enterprise signing certificates.
  • Inventory apps for App Group entitlements. Extract the entitlements of every internal and vendor-supplied enterprise IPA with codesign -d --entitlements :- Payload/App.app. Any app carrying com.apple.security.application-groups is a potential worse_query host if it’s compromised through supply-chain injection or XSS in an embedded hybrid bridge.
  • Watch endpoint telemetry for odd syscall patterns. Where mobile threat defense agents or EMM telemetry exist, look for bursts of fsgetpath calls (thousands per second suggest an inode sweep) and for processes opening file descriptors outside their assigned container UUID.

For wallet developers: four architecture rules

Treating the iOS sandbox (NSFileProtectionComplete on files in Documents/ or Library/) as the only boundary for cryptographic secrets goes against defense in depth. When a sandbox escape appears, whether bad_query, worse_query, or a future IPC deserialization bug, every file in the app container is readable while the app runs on an unlocked phone. Audit your iOS code against these rules:

  1. Keep key material off the filesystem. Never store BIP-39 mnemonics, extended private keys (xprv), unencrypted JSON keystores, or raw private key bytes in NSUserDefaults, .plist files, SQLite, Realm, MMKV, or WKWebView localStorage/IndexedDB, and don’t protect them with a static key either.
  2. Bind secrets to the Keychain and Secure Enclave. Store seed phrases and symmetric wrapping keys only in the iOS Keychain with kSecAttrAccessibleWhenUnlockedThisDeviceOnly or kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, and require biometrics (kSecAccessControlBiometryCurrentSet) or the device passcode (kSecAccessControlDevicePasscode) through SecAccessControlCreateWithFlags. securityd isolates Keychain items by entitlement signatures rather than file paths, so a container escape like worse_query can’t read them.
  3. Scrub WKWebView and network caches. In hybrid wallets and apps with a dApp browser, never write sensitive RPC responses, session credentials, or decrypted wallet state to NSURLCache or a persistent WKWebsiteDataStore. Use [WKWebsiteDataStore nonPersistentDataStore] for sensitive signing flows.
  4. Keep secrets out of shared App Groups. Treat /var/mobile/Containers/Shared/AppGroup/<UUID>/ as a public bulletin board. Write only non-sensitive display data there for widgets, such as public addresses or cached fiat portfolio totals. Session tokens, API keys, and cryptographic secrets stay out.

Until Apple updates containermanagerd and the XNU VFS and sandbox hooks to cut off the query abuse and restrict cross-container fsgetpath resolution, and until forcequitOS confirms the proof of concept fails on shipping firmware, worse_query remains an unpatched userland bug that puts crypto custody on iOS at risk without any kernel exploit.

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Your contribution powers free tutorials, hands-on labs, and security resources.

Why your support matters:
  • Writeup Access: Get complete writeup access within 12 hours
  • Zero paywalls: Keep the main content 100% free for learners worldwide

Perks for one-time supporters:
☕️ $5: Shoutout in Buy Me a Coffee
🛡️ $8: Fast-track Access to Live Webinars
💻 $10: Vote on future tutorial topics + exclusive AMA access

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

If you like this post, then please share it:

News

Discover more from The CyberSec Guru

Subscribe to get the latest posts sent to your email!

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.