BUG BOUNTYFIELD MANUAL
Reusable module
Markdown
0 / 7 checkedChecks last until this page reloads.

iOS signing capabilities, links and protected data

Connect entitlements and application groups to actual callers, URL transitions and protected key use.

Investigation sequence
  1. 01Identify signed build
  2. 02Map capabilities
  3. 03Observe normal access
  4. 04Change caller or lock state
  5. 05Verify release result
  6. 06Clean fixtures

At each step: retain the control → record the observation → continue only while the next boundary is understood.

Used in these playbooks#

Setup and invariant#

Prepare a Mac with Xcode tooling and an owned supported device. Record bundle ID, build, signing team, distribution channel, OS, and artifact hash. Keep device IPA, simulator build, enterprise build, and re-signed copy separate. Create two synthetic accounts and one private document whose marker can be recognized without collecting other data.

Invariant: links and extensions cannot borrow capabilities outside their intended trust relationship, and sensitive data/key use respects the promised authentication and lock state. Entitlements describe granted capabilities; they do not demonstrate that an unrelated app can exercise them. Apple enforces application-group relationships through signing and sandbox rules. App protection and groups.

Procedure and command sheet#

  1. Inspect the unchanged bundle. On macOS, inspect the main app and repeat for each embedded extension. The entitlement command writes to stdout; it does not re-sign the app.
plutil -p ./Payload/Lab.app/Info.plist
codesign -dv --verbose=4 ./Payload/Lab.app
codesign -d --entitlements - ./Payload/Lab.app

Capture CFBundleURLTypes, associated domains, App Groups, Keychain access groups, extension points, and ATS exceptions. A capability missing from Info.plist may be in the signature, so inspect both. OWASP entitlement extraction, OWASP plist tooling.

  1. Build a capability table. Use columns for main app, extension, signing identity, shared container, shared secret, intended consumer, and external input. In source-available work, locate storage and callback code:
rg -n 'SecItem(Add|CopyMatching)|kSecAttrAccessible|kSecAttrAccessGroup|LAContext|evaluatePolicy' ./source
rg -n 'openURL|continueUserActivity|WKScriptMessageHandler|containerURL' ./source

Matches identify implementation paths, not vulnerabilities. Trace the actual access group/class and the operation that uses the retrieved key; do not infer a security boundary from a biometric-looking screen alone.

  1. Compare link transitions. Open one normal universal link and one custom-scheme route using an owned Notes/browser fixture. Repeat while logged out, after account switching, and with a mismatched synthetic resource. Record browser/app routing separately from account authorization. Universal links require website/app association; custom schemes have different ownership guarantees. For OAuth callbacks, reuse identity/session tests; for object access, use the authorization matrix. Apple universal-link model.

  2. Test one protected-state transition. Establish legitimate access when unlocked, then lock the device and exercise only the supported background/extension path. Compare with a denied access class or an operation requiring fresh user presence. Record whether sensitive plaintext or usable key operations become available, not simply whether encrypted bytes remain on disk. Keychain accessibility, synchronization, and user-presence policy serve different purposes. Keychain data protection.

  3. Confirm the caller model. Test extension input with a harmless imported document or URL through the normal share sheet. Reuse file boundaries and browser trust when files or WKWebView messages are involved. An attacker app signed with the target's team or a jailbreak granting container access invalidates an ordinary-app claim; disclose such constraints and seek an unchanged-build reproduction.

Completion and cleanup#

  • Preserve exact build, signature, device state, input and expected denial.
  • Explain why background access violates a product promise rather than an intended feature.
  • Keep proof to the seeded document or one reversible operation.
  • Remove synthetic links/documents and testing profiles; revoke lab sessions and restore the owned device configuration.

Native authentication continuation#

For browser-based sign-in, record the actual authentication session, callback scheme or associated-domain route, and the pending login or account-linking transaction. In the local identity fixture, begin independent A/B attempts and return A's callback while B is pending. Compare the resulting account and token decision with an untouched control. Route matching alone does not establish that a callback belongs to the current transaction. Reuse federation/token trust for the complete code/PKCE/issuer checks; RFC 8252's native-client model separates the external authorization agent from the native client. OAuth for native apps.

For passkeys or local authentication, record whether the protected operation is a remote session issuance or local use of a protected key. Trace the returned credential to the server and apply authenticator lifecycle. A successful Face ID prompt is not evidence that server-side challenge and account binding are correct. Inspect local paths without changing signing identities:

rg -n 'ASWebAuthenticationSession|ASAuthorization|code_verifier|redirect_uri|SecKeyCreateSignature' ./source
  • Record callback routing, pending transaction and final account separately.
  • Exercise cancellation/expiration and an account switch with synthetic identities.
  • Preserve the valid control and confirm no useful credential is issued for the mismatched transaction.

Vulnerability reverse references#

Nearby shared procedures#

Object, function, and property authorization · Authentication, recovery, federation, and session lifecycle · Trace input into queries, commands, and templates · Browser execution, cross-origin reads, and forged actions · Uploads, downloads, paths, archives, and XML · Workflow invariants, replay, idempotency, and races · REST, GraphQL, gRPC, WebSocket, and SSE permission parity · Source review: entry point to protected operation