Port MASTG-TEST-0069: Testing App Permissions (ios) (by @appknox)#3673
Port MASTG-TEST-0069: Testing App Permissions (ios) (by @appknox)#3673sk3l10x1ng wants to merge 5 commits intoOWASP:masterfrom
Conversation
|
|
||
| If an app declares entitlements that are not justified by its core functionality, it gains access to privileged capabilities beyond standard sandbox restrictions — such as HomeKit, HealthKit, VPN configuration, or iCloud containers. This can lead to unauthorized access to sensitive user data, expanded attack surface, or privacy violations through excessive privilege. | ||
|
|
||
| On iOS, entitlements are declared in the provisioning profile (`embedded.mobileprovision`) as a cryptographically signed property list. They represent permissions granted by Apple's provisioning system for capabilities that go beyond the default app sandbox. |
There was a problem hiding this comment.
embedded.mobileprovision is available only on apps built for: Development, Ad Hoc distribution, Enterprise distribution. We might need to mention it, so the testers won't have issues when searching for them?
| func requestAllPermissionsSequentially(completion: @escaping (String) -> Void) { | ||
| self.completionHandler = completion | ||
| resetState() | ||
| requestLocationPermission() |
There was a problem hiding this comment.
Just for clarity:
| requestLocationPermission() | |
| requestLocationPermission() | |
| // Subsequent requests are triggered within delegates or callbacks |
|
|
||
| private func requestLocationPermission() { | ||
| locationManager.requestWhenInUseAuthorization() | ||
| locationManager.requestAlwaysAuthorization() |
There was a problem hiding this comment.
Shouldn't we call requestAlwaysAuthorization() after the request for requestWhenInUseAuthorization() finishes?
In other words, why don't we call requestAlwaysAuthorization() from func locationManager(.., didChangeAuthorization status: CLAuthorizationStatus)
| completionHandler?(results) | ||
| } | ||
|
|
||
| func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { |
There was a problem hiding this comment.
| if granted { | ||
| manager.startUpdatingLocation() | ||
| } | ||
| requestCameraPermission() |
There was a problem hiding this comment.
Shouldn't we call it on the main thread similarly to the other cases?
| requestCameraPermission() | |
| DispatchQueue.main.async { | |
| requestCameraPermission() | |
| } |
Or even wrap a bigger part of code?
|
|
||
| ## Overview | ||
|
|
||
| If an app embeds entitlements in its binary that are not justified by its core functionality, it gains access to privileged capabilities such as HomeKit, HealthKit, VPN configuration, or shared app groups. This can lead to unauthorized access to sensitive user data, an expanded attack surface, or privacy violations through excessive privilege. |
There was a problem hiding this comment.
Can we have a Knowledge page about embedded entitlements and external one. Just to clarify why there are both places. We could also describe there that an app needs to have a usage description in Info.plist
There was a problem hiding this comment.
Pull request overview
This PR ports the legacy iOS test MASTG-TEST-0069 (Testing App Permissions) to the v2 structure by deprecating the v1 test and adding new v2 test(s), an iOS technique page, and multiple iOS demos intended to demonstrate permission declarations and runtime permission usage.
Changes:
- Deprecates the v1 test
tests/ios/MASVS-PLATFORM/MASTG-TEST-0069.mdand links it to new v2 coverage. - Adds four new v2 iOS test pages related to purpose strings and entitlements under
tests-beta/ios/. - Adds a new iOS technique page and several new iOS demos (static and dynamic) with scripts and captured outputs.
Reviewed changes
Copilot reviewed 20 out of 23 changed files in this pull request and generated 30 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/ios/MASVS-PLATFORM/MASTG-TEST-0069.md | Marks the v1 test as deprecated and attempts to point to v2 replacements via covered_by. |
| tests-beta/ios/MASVS-PRIVACY/MASTG-TEST-0x69.md | Adds a new v2 static test for excessive Info.plist purpose strings. |
| tests-beta/ios/MASVS-PRIVACY/MASTG-TEST-0x69-1.md | Adds a new v2 static test for entitlements in embedded.mobileprovision. |
| tests-beta/ios/MASVS-PRIVACY/MASTG-TEST-0x69-2.md | Adds a new v2 static test for entitlements embedded in the app binary. |
| tests-beta/ios/MASVS-PRIVACY/MASTG-TEST-0x69-3.md | Adds a new v2 dynamic test for runtime tracing of permission API calls. |
| techniques/ios/MASTG-TECH-0x69.md | Adds a technique page intended to explain how to obtain and review iOS permissions/capabilities. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69/MASTG-DEMO-0x69.md | Adds a demo documenting purpose strings in Info.plist. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69/MastgTest.swift | Adds a Swift sample that requests many permissions sequentially for demo purposes. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69/Info.plist | Adds a demo Info.plist artifact used by the purpose-string demo. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69/run.sh | Adds an automation script to extract/grep purpose-string keys from Info.plist. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69/output.txt | Adds captured output listing UsageDescription keys found in the plist. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69/embedded.mobileprovision | Adds a provisioning profile artifact used by entitlement demos. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-1/MASTG-DEMO-0x69-1.md | Adds a demo documenting entitlements in embedded.mobileprovision. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-1/run.sh | Adds an automation script to decode the provisioning profile with security cms. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-1/output.txt | Adds captured decoded provisioning-profile output. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-2/MASTG-DEMO-0x69-2.md | Adds a demo documenting entitlements extracted from the signed binary. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-2/run.sh | Adds an automation script using rabin2 to extract entitlements. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-2/output.txt | Adds captured entitlements output. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-3/MASTG-DEMO-0x69-3.md | Adds a demo documenting runtime tracing of permission APIs with Frida. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-3/run.sh | Adds a Frida spawn script for the runtime tracing demo. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-3/output.txt | Adds captured Frida output showing permission API calls. |
| demos/ios/MASVS-PRIVACY/MASTG-DEMO-0x69-3/script.js | Adds a Frida script intended to hook many iOS permission-related APIs. |
| id: MASTG-TEST-0x69 | ||
| type: [static] | ||
| weakness: MASWE-0117 | ||
| profiles: [L1, L2] |
There was a problem hiding this comment.
For MASVS-PRIVACY tests, profiles is typically [P] (e.g., tests-beta/ios/MASVS-PRIVACY/MASTG-TEST-0281.md:7 and tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0254.md:7). Using [L1, L2] here looks inconsistent; please switch to [P] (or justify why this permission-privacy test belongs to L1/L2).
| ## Observation | ||
|
|
||
| The output lists 16 purpose strings found in the `Info.plist` file, indicating the app declares access to a wide range of protected resources. | ||
|
|
||
| {{ output.txt }} |
There was a problem hiding this comment.
The demo claims it finds “purpose strings” and the test expects key/value pairs, but run.sh only greps for UsageDescription and the committed output.txt contains only <key>...UsageDescription</key> entries (no <string>...). Update the script/output to include the associated description values, or adjust the text to accurately state that only keys are collected.
There was a problem hiding this comment.
True, it's not just about the keys being there. They also MUST have an actual appropriate description that serves as rationale about the need for that permission.
| @@ -0,0 +1 @@ | |||
| security cms -D -i ../MASTG-DEMO-0x69/embedded.mobileprovision > output.txt No newline at end of file | |||
There was a problem hiding this comment.
run.sh is missing a shebang (other demos use #!/bin/bash) and basic safety flags. Add a shebang and set -euo pipefail so the demo fails fast and can be executed consistently by automation.
closes #2969