Hacktricks-skills ios-universal-links-pentest
Pentest iOS Universal Links by extracting entitlements, fetching apple-app-site-association (AASA) files, and identifying misconfigurations like over-broad paths, missing server validation, and wildcard subdomains. Use this skill whenever the user mentions iOS app security, universal links, deep links, AASA files, associated domains, or wants to test mobile app link handling vulnerabilities.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/mobile-pentesting/ios-pentesting/ios-universal-links/SKILL.MDiOS Universal Links Pentesting
A skill for security testing iOS Universal Links configurations to identify vulnerabilities that could lead to link hijacking, phishing, or unauthorized app behavior.
What This Skill Does
This skill helps you:
- Extract
domains from iOS app entitlementsapplinks: - Fetch and analyze
(AASA) filesapple-app-site-association - Identify common vulnerabilities in Universal Links configuration
- Validate server-side path handling
- Generate a security assessment report
When to Use This Skill
Use this skill when:
- Testing iOS app security and Universal Links implementation
- Analyzing
files for misconfigurationsapple-app-site-association - Enumerating associated domains from iOS entitlements
- Investigating potential Universal Link hijacking vulnerabilities
- Auditing deep link security in mobile applications
Workflow Overview
1. Extract entitlements → 2. Parse applinks domains → 3. Fetch AASA files → 4. Validate configuration → 5. Report findings
Step 1: Extract Associated Domains from Entitlements
From Xcode Project
If you have access to the Xcode project, check the Capabilities tab or the
.entitlements file:
<key>com.apple.developer.associated-domains</key> <array> <string>applinks:example.com</string> <string>applinks:app.example.com</string> </array>
From Compiled Binary
Extract entitlements from a compiled
.app or .ipa file:
# From .app bundle plutil -p YourApp.app/Info.plist | grep -A 10 "com.apple.developer.associated-domains" # Or extract the entitlements file directly plutil -p YourApp.app/embedded.mobileprovision 2>/dev/null || \ strings YourApp.app/YourApp | grep -A 5 "associated-domains"
Using the Helper Script
If you have an entitlements XML file, use the extraction script:
./scripts/extract_applinks_domains.sh ent.xml
This outputs all
applinks: domains, one per line.
Step 2: Fetch AASA Files
The
apple-app-site-association file should be at:
https://<domain>/apple-app-site-associationhttps://<domain>/.well-known/apple-app-site-association
Using the Helper Script
./scripts/fetch_aasa_files.sh domain1.com domain2.com
Or pipe domains from the extraction script:
./scripts/extract_applinks_domains.sh ent.xml | xargs -I {} ./scripts/fetch_aasa_files.sh {}
Manual Fetch
curl -sk "https://example.com/.well-known/apple-app-site-association" | jq '.' curl -sk "https://example.com/apple-app-site-association" | jq '.'
Step 3: Validate AASA Configuration
Common Vulnerabilities to Check
| # | Weakness | How to Test | Impact |
|---|---|---|---|
| 1 | Over-broad paths ( or wildcards like ) | Inspect AASA for , trailing slashes, or rules | Universal link hijacking - malicious app can claim all matching links |
| 2 | Missing server-side validation | Request non-existing resources; anything other than 404 is suspicious | Attacker can host arbitrary content behind allowed paths |
| 3 | App-side URL handling without whitelisting | Look for direct / calls | URL spoofing, bypassing browser safety checks |
| 4 | Wildcard subdomains () | for in entitlements | Subdomain takeover grants automatic Universal Link binding |
Using the Validation Script
./scripts/validate_aasa.sh aasa_file.json
This checks for:
- Over-broad path patterns
- Wildcard usage
- Missing required fields
- Common misconfigurations
Step 4: Server-Side Path Validation
Test that the server returns 404 for undefined paths:
# Test various paths that might match wildcard rules for path in "/nonexistent" "/a/evil" "/a/evil?_p_dp=1" "/unknown/path"; do echo "Testing: $path" curl -sI "https://example.com$path" | head -1 done
Expected:
HTTP/1.1 404 Not Found
Suspicious: HTTP/1.1 200 OK or HTTP/1.1 302 Found
Step 5: Generate Assessment Report
Create a structured report of findings:
# iOS Universal Links Security Assessment ## Target Application - App Name: [Name] - Bundle ID: [Bundle ID] - Version: [Version] ## Associated Domains | Domain | AASA Found | Status | |--------|------------|--------| | example.com | Yes | ⚠️ Over-broad paths | | app.example.com | No | ❌ Missing AASA | ## Vulnerabilities Found ### 1. Over-broad Path Configuration - **Domain**: example.com - **Issue**: Path pattern `"/a/*"` matches all sub-paths - **Risk**: High - Universal link hijacking possible - **Reference**: CVE-2024-10474, Temu.com bug bounty (May 2025) ### 2. Missing Server-Side Validation - **Domain**: example.com - **Issue**: Non-existent paths return 200 instead of 404 - **Risk**: Medium - Phishing content can be served ## Recommendations 1. Restrict path patterns to specific, known routes 2. Ensure server returns 404 for undefined paths 3. Implement app-side URL scheme/host whitelisting 4. Remove wildcard subdomain entries if not needed ## Tools Used - AASA Validator: https://branch.io/resources/aasa-validator/ - Knil: https://github.com/ethanhuang13/knil - universal-link-validator: https://github.com/urbangems/universal-link-validator
AASA File Structure Reference
{ "applinks": { "apps": [], "details": [ { "appID": "TEAMID.com.example.app", "paths": ["/specific/path", "/another/path"] } ] }, "appclips": { "apps": [], "details": [ { "appID": "TEAMID.com.example.app", "paths": ["/appclip/path"] } ] } }
iOS 11+ Components Syntax
{ "applinks": { "apps": [], "details": [ { "appID": "TEAMID.com.example.app", "components": [ { "%path": "/users/:id", "?": { "action": ["view", "edit"] } } ] } ] } }
Quick Checklist
- Extract entitlements and enumerate every
entryapplinks: - Download AASA for each entry and audit for wildcards
- Verify the web server returns 404 for undefined paths
- In the binary, confirm that only trusted hosts/schemes are handled
- If using
syntax (iOS 11+), fuzz query-parameter rulescomponents - Check for wildcard subdomains (
) in entitlements*.example.com - Validate AASA file is served with correct MIME type (
)application/json - Ensure AASA is accessible via HTTPS only
References
- OWASP MASTG - iOS Universal Links Testing
- Mobile Security Testing Guide - iOS Platform Interaction
- Apple Developer Documentation - Universal Links
- CVE-2024-10474 - Mozilla Focus Universal Link Bypass
- Temu.com Universal Link Hijacking Case Study
Tools
- GetUniversal.link - AASA file verification and testing
- Knil - iOS utility to tap-test Universal Links on device
- universal-link-validator - CLI/web validator for AASA conformance
- AASA Validator - Online AASA file validator