Universal Links should provide bundle ID of originating app
| Originator: | Footpad01 | ||
| Number: | rdar://27878679 | Date Originated: | 16-Aug-2016 |
| Status: | Closed | Resolved: | No |
| Product: | iOS SDK | Product Version: | |
| Classification: | Working as intended | Reproducible: |
Summary: When an app handles a Universal Link, it receives an NSUserActivity with an activityType of NSUserActivityTypeBrowsingWeb[1]. There is no indication provided of the application that the Universal Link was opened in, such as the app's Bundle ID. This request is to have the Bundle ID of the originating app be provided to the app opening the Universal Link. Why? Universal Links solves the security problem inherent with custom URL schemes[1] (e.g. "com.myapp://"), wherein any app can declare it handles any custom URL scheme and how iOS picks the app that handles a URL with a custom scheme is undefined[2]. However, it creates a new security issue that custom URL schemes do not have, which is the inability to trust the identity of the caller. When handling custom URL schemes, the bundle ID of the calling application is returned to the UIApplicationDelegate methods. This does not appear to exist for the Universal Links callback provided today. For example, consider the follow scenario using only custom URL schemes and not Universal Links: App A provides a secure feature that any other app can call and receive a response from. In order to ensure that the app is not malicious, App A will only handle a request if it is valid for the calling app's Bundle ID. When the calling app has been validated, the feature will run and return some (sensitive) data back to the calling app. While the above is possible today using custom URL schemes because the Bundle ID is provided, App A will not be able to validate that the request is from a malicious client or not. [1] https://developer.apple.com/library/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html [2] https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW11 Steps to Reproduce: 1. Set up an app to handle Universal Links 2. Open a Universal Link with the app. 3. Inspect the input values provided to -[UIApplicationDelegate application:continueUserActivity:restorationHandler:] Expected Results: I expect to be able to retrieve the Bundle ID of the application that the Universal Link was opened from. Because it comes from the OS, I expect that I can trust the validity of it. Actual Results: -[UIApplicationDelegate application:continueUserActivity:restorationHandler:] does not provide any (documented) way to retrieve the Bundle ID of the application that the Universal Link was opened from. Version: N/A Notes: Configuration: N/A Attachments:
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
(Response from Apple:)
Please know that our engineering team has determined that this issue behaves as intended based on the information provided.
This is intentional.
The security issue described is an issue in the developer's security model. The developer already cannot trust the URL regardless of origin (even knowing the source's bundle identifier) because the source app could be compromised or gamed into producing a dangerous URL (consider an app that naïvely punches out links from a UIWebView.) Dangerous actions should generally not be performed from outside your application's context without confirming with the user first.
As discussed in WWDC 2015's session 509: Seamless Linking to Your App, the developer should be validating incoming URLs before performing any dangerous action based on the URL's contents. For example, if a request comes in via a URL to delete data, the developer could validate requests via a trusted server (over a secure protocol such as HTTPS) to ensure that the user actually requested the action.