Android components, intents and deep links
Trace ordinary-app inputs through exported components, URI grants and links to one protected operation.
- 01Fingerprint release
- 02Map caller authority
- 03Record valid baseline
- 04Change one input
- 05Verify boundary
- 06Restore lab
At each step: retain the control → record the observation → continue only while the next boundary is understood.
Used in these playbooks#
Setup and invariant#
Use an owned emulator/device, the scoped release APK and relevant splits, SDK Platform Tools, APK Analyzer, and an ordinary companion application you control. Seed a private record BB-ANDROID-01 and a deliberately shareable record. Keep ADB for orchestration and observation; its shell identity is not equivalent to an ordinary installed app.
Invariant: an external caller receives only the component actions and URI grants deliberately delegated to that caller. A public activity must still enforce the sensitive operation's requirements. Export defaults vary across components and platform versions, so inspect resolved package state as well as the manifest. Android component exposure.
Procedure and command sheet#
- Fingerprint. Record package, version, target SDK, device API, signer, and release/debug state. These commands inspect a local APK and one selected device:
adb devices -l
adb -s DEVICE_SERIAL shell pm path com.example.lab
adb -s DEVICE_SERIAL shell dumpsys package com.example.lab
apkanalyzer apk summary ./app.apk
apkanalyzer manifest print ./app.apk
apkanalyzer manifest permissions ./app.apk
Use the printed manifest to create rows for activity/service/receiver/provider, export state, permission, URI authority, grant flags, external input, and protected operation. ADB, APK Analyzer.
Establish a baseline. Exercise the intended share or navigation action. Record exactly which URI, recipient, and capability were granted. From the companion app, request only the seeded record through
ContentResolver; retain the result or exception. A provider may require permissions or a temporary grant even when externally addressable. Provider access model.Run one negative control. Repeat without the grant, with the second seeded URI, or from a fresh ordinary caller. The control must change only one condition. For a link, compare normal login with logged-out and account-switched states. ADB can launch a harmless route for diagnosis:
adb -s DEVICE_SERIAL shell am start -W -a android.intent.action.VIEW -d 'labapp://item/BB-ANDROID-01' com.example.lab
Use the actual discovered scheme/package, and repeat any result from the companion app. If links reach the backend, reuse the authorization matrix and identity/session experiments. Link verification does not validate arbitrary parameters. Deep-link risks.
Inspect delegation. Trace nested intents, forwarded extras, and obtained PendingIntent tokens. Determine which action/destination remains caller-controlled. Check one harmless alternate destination or repeat of an intended single-use action. Record OS behavior: Android 16 adds default intent-redirection hardening, so reproduce on the supported version rather than extrapolating from an older emulator. Intent redirection, PendingIntent delegation.
Decide and retain evidence. A report needs caller identity/permissions, precise URI or intent, eligible build, expected denial, and the protected result. An exported activity opening a public screen, a denied request, or access obtained only after granting the attacker target-equivalent privilege is not this finding. Route path handling into file boundaries, and WebView-origin questions into browser trust.
Completion and cleanup#
- Compare intended recipient, unauthorized caller, and revoked-grant state.
- Repeat the smallest result without ADB-only privileges.
- Distinguish data reads, harmless navigation, and state-changing operations.
- Record minimum OS, target SDK, interactions, and ownership assumptions.
- Revoke temporary shares, remove companion-app fixtures, and restore the emulator snapshot after exporting redacted evidence.
Native authentication continuation#
Treat OAuth routing and authorization as separate decisions. Record the external authorization UI, registered callback, app instance, pending transaction and PKCE verifier lifecycle. With two owned local login attempts, compare a normal return with a callback delivered to the other pending attempt. Then compare the correct verifier with the other attempt's verifier at the local token endpoint. A intercepted code that cannot be redeemed is a protected control, not account takeover. Use federation/token trust for issuer, code, state and token decisions. Native public clients require PKCE; an embedded shared client secret is not a confidential per-installation secret. RFC 8252, PKCE.
For passkeys, follow Credential Manager's result into the relying-party server; the credential-selection UI does not finish server authentication. Reuse authenticator lifecycle for challenge, credential/account binding and required verification flags. Record the release signer and native origin/association configuration; do not infer the production origin allowlist from a re-signed APK. Android separates the client, credential provider and verifying server. Credential Manager architecture.
rg -n 'code_verifier|code_challenge|redirect_uri|CredentialManager|PublicKeyCredential' ./source
- Callback receiver and backend authenticated identity are both observed.
- Cross-attempt, expired-attempt and valid-attempt controls use fresh codes.
- Re-signing, debug credentials and altered app links are disclosed.
Vulnerability reverse references#
- Exported Android component exposes a protected operation — An externally reachable activity, service or receiver performs work that its caller is not entitled to request.
- Content-provider permission or URI-grant escape — A recipient obtains data or file capabilities beyond the URI and permissions deliberately shared with it.
- Nested intent redirects application authority — An exported entry point forwards attacker-supplied intent fields into a protected destination using the target application’s authority.
- PendingIntent grants unintended mutable or replayable authority — A recipient can alter or reuse a delegated action beyond its intended destination, parameters or lifetime.
- Mobile link handler trusts routing as authorization — An externally supplied custom or universal/app link reaches a protected client operation without validating the route input and current security context.
- Untrusted WebView content reaches a native bridge — A page or frame controlled outside the trusted app origin can invoke native capabilities through a shipped WebView bridge.
- Private client content leaks through a lower-trust display or sharing channel — A private marker appears in a notification, background snapshot, clipboard or another user-visible channel outside its promised audience.
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