iOS Universal Links Abuse in Bug Bounty Programs
Universal Links are supposed to open https URLs in the owning app when the association file says so. Abuse happens when that file is too broad, served insecurely, or when the app still honors custom URL schemes for the same sensitive flows.
I've lost time chasing "Universal Links" that were actually just myapp:// redirects from an email. Separate the mechanisms before you write severity.
Read the association file like a scope map
Fetch https://target/.well-known/apple-app-site-association (and the older root path). Confirm Content-Type, HTTPS, and no intermediate redirects that break Apple's fetch rules. Parse applinks.details[].paths and components.
Wildcards matter:
*or/*claims the whole site—password reset, OAuth callback, magic login, everythingNOT /static/*exclusions that leave/auth/*open- Multiple apps (team ID + bundle ID) claiming overlapping paths
If a staging team ID or an old partner app remains listed, you may install that bundle (when you legitimately own it) or report the stale association as an attack-surface finding when the program accepts configuration issues. A partner app that still claims /oauth/* after a vendor swap is a quiet footgun.
Also validate CDN caching. An outdated AASA on the edge after a path lockdown means devices may keep broad entitlements until Apple refreshes. Note the Cache-Control you observed; it strengthens a config report even when you cannot force every device to refetch.
Where the sensitive action lives
Trace password-reset and magic-link emails. Does the link stay on https://app.target.com/login?token= or bounce to target://login?token=? Custom schemes on iOS are claimable by any app that registers them. Universal Links only help if the https URL is what carries the secret and the association is tight.
For a proof: create a reset for an account you own, capture the link, and show that a second app you registered for an overlapping unverified path—or a custom scheme fallback—receives the token. Screenshots of continueUserActivity or the scheme handler with the canary token are enough. Do not social-engineer other testers' devices.
Also check whether the app opens arbitrary https URLs from a query parameter after the Universal Link lands. That turns a link-handling bug into open redirect or WebView phishing inside a trusted UI. Pasteboard and share-sheet handlers sometimes duplicate the same token parsing—worth a second look if the deeplink path looks clean.
Entitlements, Smart App Banners, and reinstall quirks
Association updates are sticky. After changing paths, delete the app, clear the association cache by reinstalling, and retest. Report the state you observed: paths claimed, apps listed, and whether Safari showed a banner or opened cold into the app. Long-pressing a link and choosing "Open in Safari" versus the app can reveal different code paths; only one of them might validate the token correctly.
Watch for deferred deep linking SDKs that copy Universal Link parameters into local storage before auth completes. If those values later drive account linking without a fresh server check, you have a logic bug sitting beside the association file issue.
Severity tracks the data in the URL. A token that grants session minting is high. A marketing deep link to /promo/spring is noise. Recommend least-privilege paths in the association file, retire custom schemes for auth, bind tokens to device/session context, and keep AASA free of stale team IDs. Apple's Universal Links documentation is the right citation when you explain why an unverified claim failed closed—or failed open.