AppSec Blog

AppSec Blog

Insecure Handling of URL Schemes in Apple's iOS

This is a guest post from security researcher Nitesh Dhanjani. Nitesh will be giving a talk on "Hacking and Securing Next Generation iPhone and iPad Apps" at SANS AppSec 2011

In this article, I will discuss the security concerns I have regarding how URL Schemes are registered and invoked in iOS.

URL Schemes, as Apple refers to them, are URL Protocol Handlers that can be invoked by the Safari browser. They can also be used by applications to launch other applications to perform certain transactions, but this use case isn?t relevant to the scope of this discussion.

In the URL Scheme Reference document, Apple lists the default URL Schemes that are registered within iOS. For example, the tel: scheme can be used to launch the Phone application. Now, imagine if a website were to contain the following HTML rendered to someone browsing using Safari on iOS:

<iframe src="tel:1-408-555-5555"></iframe>

In this situation, Safari displays an authorization dialog:


Figure 1: Dialog box in Safari requesting for user authorization to launch the Phone application


Fantastic. A malicious website should not be able to initiate a phone call without the user?s explicit permission. This is the right behavior from a security perspective.

Now, let us assume the user has Skype.app installed. Let us also assume that the user has launched Skype in the past and that application has cached the user?s credentials (this is most often the case: users on mobile devices don?t want to repeatedly enter their credentials so this is not an unfair assumption). Now, what do you think happens when a malicious site renders the following HTML?

<iframe src="skype://14085555555?call"></iframe>

In this case, Safari throws no warning, and yanks the user into Skype which immediately initiates the call. The security implications of this is obvious, including the additional abuse case where a malicious site can make Skype.app call a Skype-id who can then uncloak the victim?s identity (by analyzing the victim?s Skype-id from the incoming call).


Figure 2: Skype automatically initiating a call on iOS after being invoked by a malicious website


I contacted Apple?s security team to discuss this behavior, and their stance is that the onus is on the third-party applications (such as Skype in this case) to ask the user for authorization before performing the transaction. I also contacted Skype about this issue, but I have not heard back from them.

I do agree with Apple that third-party applications should also take part in ensuring authorization from the user, yet their stance leaves the following concerns unaddressed.

Third party applications can only ask for authorization after the user has already been yanked out of Safari. A rogue website, or a website whose client code may have been compromised by a persistent XSS, can yank the user out of the Safari browser. Since applications on iOS run in full-screen mode, this can be an annoying and jarring experience for the user.

Third party applications can only ask the user for authorization after they have been fully launched. To register a URL Scheme, application developers need to alter their Info.plist file. For example, here is a section from Skype?s Info.plist:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.skype.skype</string>
<key>CFBundleURLSchemes</key>
<array>
<string>skype</string>
</array>
</dict>
</array>

[Note: If you have a jailbroken iOS device and would like to obtain the list of URL Schemes for applications you have downloaded from the App Store, just copy over the Info.plist files for the applications onto your Mac and run the plutil tool to convert them to XML: plutil -convert xml1 Info.plist]

Next, the application needs to implement handling of the message in it?s delegate. For example:

(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
// Ask for authorization
// Perform transaction
}

Unlike the case of the tel: handler which enjoys the special privilege of requesting the user for authorization before yanking the user away from his or her browsing session in Safari, third party applications can only request authorization after they have been fully launched.

A solution to this issue is for Apple to allow third party applications an option register their URL schemes with strings for Safari to prompt and authorize prior to launching the external application.

Should Apple audit the security implications of registered URL schemes as part of its App Store approval process? Apple?s tel: handler causes Safari to ask the user for authorization before placing phone calls. The most logical explanation for this behavior is that Apple is concerned about their customers? security and doesn?t want rogue websites from being able to place arbitrary phone calls using the customer?s device.

However, since the Skype application allows for such an abuse case to succeed, and given that Apple goes to great lengths to curate applications before allowing them to be listed in the App Store, should Apple begin to audit applications for security implications of exposed URL Schemes? After all, Apple is known to reject applications that pose a security or privacy risk to their users, so why not demand secure handling of transactions invoked by URL Schemes as well?

Skype is just one example. Besides Skype, there are many additional third party applications that register URL Schemes that can be invoked remotely by Safari without any interaction from the user. See the following websites for a comprehensive list http://wiki.akosma.com/IPhone_URL_Schemes and http://handleopenurl.com/scheme.

List of registered URL Schemes not available to the average user. You can enumerate all the Info.plist files in your iPhone to ascertain the list of URL schemes your iPhone or iPad may respond to assuming you have jailbroken your iPhone. However, it may make sense for this list to be available in the Settings section of iOS so users can look at it to understand what schemes their device responds that can be invoked by arbitrary websites. Perhaps this will mostly appeal to the advanced users yet I feel it will help keep the application designers disciplined the same way the user location notification in iOS does. This will also make it easier for enterprises to figure out what third party applications to provision on their employee devices based on any badly designed URL schemes that may place company data at risk.

Note that in order to create a registry of exposed URL schemes, Apple cannot simply parse information from Info.plist because it only contains the initial protocol string. In other words, the skype: handler responds to skype://[phone_or_id]?call and skype://[phone_or_id]?chat but only the skype: protocol is listed Info.plist while the actual parsing of the URL is performed in code. Therefore, in order to implement this proposed registry system, Apple will have to require developers to disclose all patterns within a file such as Info.plist.

I feel the risk posed by how URL Schemes are handled in iOS is significant because it allows external sources to launch applications without user interaction and perform registered transactions. Third party developers, including developers who create custom applications for enterprise use, need to realize their URL handlers can be invoked by a user landing upon a malicious website and not assume that the user authorized it. Apple also needs to step up and allow the registration of URL Schemes that can instruct Safari to throw an authorization request prior to yanking the user away into the application.

Given the prevalence and ever growing popularity of iOS devices, we have come to depend on Apple?s platform with our personal, financial, and health-care data. As such, we need to make sure both the platforms and the custom applications iOS devices are designed securely. I hope this writeup helped increase awareness of the need to implement URL Schemes securely and what Apple can do to assist in making this happen.

If you liked this post check out SANS' new class on Secure iOS App Development.

22 Comments

Posted November 08, 2010 at 7:34 PM | Permalink | Reply

Brian M

This is a good observation, although they don't necessarily need all combinations of urls to be registered. Instead, they could have regex's registered to display different messages, like: "would you like Skype to call this number" versus "... Chat with this number". Then have a default fallback. Add a menu in the settings for "don't prompt" so the user can be rid of the nag screens, and allow the developer to permit URL handling without messages.

I think this is in apples best interest. I think apple would be able to handle that fairly easily.

Posted November 09, 2010 at 1:36 AM | Permalink | Reply

Rick

You do not need a jailbroken device to look at the Info.plist files of any app you have purchased or downloaded. All apps get stored in iTunes. On a Mac you can find all your apps in

$HOME/Music/iTunes/Mobile Applications

You will find all the .ipa files for the apps. These are just zip files. The Info.plist file is in each ipa file.

This ability to launch 3rd party apps from a URL in a web browser is also used to allow 3rd party apps to launch other 3rd party apps or some of Apple's apps.

The simplest solution to this whole problem would be for Mobile Safari to confirm the launch of any app from a URL in a web page. Done. No changes to 3rd party apps. No extra work by anyone except for a quick change to Mobile Safari.

Then there is the same issue when viewing an email on an iOS device. A link in the email could also launch another app. But this does require the user to actually tap on the link in the email.

Posted November 09, 2010 at 1:46 AM | Permalink | Reply

Nobody

Even simpler. Execute the callback before fully leaving safari and let the app developer parse the uri however they want.

Posted November 09, 2010 at 2:08 AM | Permalink | Reply

Nitesh Dhanjani

Rick: Cool, thanks for the tip on how to get at Info.plist files without having to jailbreak.

Posted November 09, 2010 at 2:39 AM | Permalink | Reply

Andrei Tchijov

How is this iOS problem? Skype choose to initiate call unconditionally when invoked via URL. When you click on URL with registered handler, all iOS does is firing application and informing it that it was started in response to the URL. From this point on, it is application's responsibility to do 'right thing'.

Posted November 09, 2010 at 2:53 AM | Permalink | Reply

Nitesh Dhanjani

Hi Andrei: thanks for your comment. I agree, Skype should take part in authorizing the transaction, and that is why I attempted to contact Skype about this but they never wrote back to me. Additionally, it is my opinion that Safari in iOS, like other sane browsers, should prompt the user before launching an external app. This issue is amplified in iOS because the user is yanked out into an arbitrary app since everything is full screen and authorization from external apps in iOS can only occur after they are fully launched - so Safari on iOS must also do it's part in warning the user.

Posted November 09, 2010 at 3:05 AM | Permalink | Reply

Ben Gross

Setting your Skype status to offline prevents this. Skype will popup a message that says "You're offline. You need to be online to make a call."

Clearly application developers need to consider the security implications of their URL handlers. It seems like a good idea for Apple to require app developers to explicitly list all URL handlers when submitting the app. Ideally, Apple would provide a method to list all of the active URL handlers in iOS.

Posted November 09, 2010 at 3:17 AM | Permalink | Reply

Andrei Tchijov

@Ben Gross. Apple does exactly this. In order for an iOS application been invocable via URL you have to declare such URL in your application configuration file. Look for "CFBundleURLTypes" in original article.

Posted November 09, 2010 at 3:24 AM | Permalink | Reply

Andrei Tchijov

@Nitesh. Basically you propose to punish every single app which use URL lunching (by requiring users of all these applications to do extra click) in order to prevent "bad things" from happening in case of few applications which did not think through all security implications of this mechanism? I do not really believe in this approach. You can not safeguard against everything. If you go along this road you will end up in Vista land - where every time you attempt to do anything you get confirmation dialog which asks you to confirm that this is really what you want to do. It is annoying as hell on desktop and it will be down right unacceptable on the phone.

Posted November 09, 2010 at 3:36 AM | Permalink | Reply

Friendly Grammar Gal

Thanks for this article!

Note, typo/grammar: "handling of the message in it?s delegate" should be "handling of the message in its delegate".

Posted November 09, 2010 at 4:15 AM | Permalink | Reply

Nitesh Dhanjani

Anrei: no I do not propose a dialog box for every event. If you reread the article, perhaps that will become clear to you.

Posted November 09, 2010 at 12:30 PM | Permalink | Reply

Matthias

I agree with Nitesh. Having a dialog popup for such things is far more convenient than an unexpected application switch.

Maybe this can be filtered based on the condition if the action was user-initiated or not (like this iframe example).

And I think this should be handled by WebKit in general, not just by Safari. :-)

Posted November 09, 2010 at 1:17 PM | Permalink | Reply

Henrich C. Poehls

The same behaviour is shown in Mac OSX (10.6.4) at least with Skype Version 2.8.0.851. A click on initiates a call without asking. So this problem of Skype is persistant at least in the Mac OSX environment.

Posted November 09, 2010 at 3:13 PM | Permalink | Reply

zDen

Dont you know that thats just the way it should work and it works same way in every platform? Just try it in your desktop browser and you will be surprised. Maybe Skype should ask confirmation when making call but you can always hit cancel so thats not an issue.

Posted November 09, 2010 at 3:25 PM | Permalink | Reply

GsE

I will have to tend to agree with Apple. This vulnerability is the application's issue and not the OS or the URI handler. Basically it comes down to the application inherently trusting data coming from somewhere else. Good input validation should check for acceptable data and have the functionality to handle malicious data, be it by a warning popup or the like.

I am not shocked, but rather saddened at Skype's non-responsiveness on your contact.

Posted November 09, 2010 at 4:08 PM | Permalink | Reply

Robby D

Re: Brian's comment:
Though this would address, to some extent, the concerns raised in the article, you would then need a way for enterprise app developers to disable the "don't ask" option, or to setup "app control" for the enterprise that selectively disables it. This would allow the enterprise to have some control over the security of their data without relying on the user. Allowing the app to register a prompt with Safari would be a cleaner &amp; more straightforward way to deal with the issue. It would allow Apple to keep the onus on the app developer, if they prefer it that way, while allowing the app to present a prompt before it is launched. -R

Posted November 09, 2010 at 4:19 PM | Permalink | Reply

Daniel

Matthias: User initiated or not - some actions should never be allowed without approval. The target of a link is often not visible before clicking/tapping it.

I think the correct solution would be for the OS to always ask - unless the App-developer has deemed the protocol/action safe AND the user explicitely has agreed to auto accept. And a system wide settings panel to grant/revoke auto accept permissions.

Posted November 09, 2010 at 11:25 PM | Permalink | Reply

Brian M

Re: Robby D
Indeed. Apple does have their enterprise tools, so having a checkbox for 'prevent URL alert suppression' or similar would be in order.

A regex could have several values associated with it too (and a default failback could also have values). Things like:
1 - Message to provide the user (backreferenced with the regex for easy reading).
2 - "Always allow" enable/suppress, so the developer could force the user to say yes/no, without double prompting. Or allow the user to say "yes, this is safe to do next time".
3 - "Auto-allow", enabling the developer to say "this is safe, just let it call through". This may seem jarring, but with multi-tasking, its not really all that bad. Plus, its annoying having to "yes, allow" constantly. With an 'always allow' its not so much of an issue though. Apple does this on OS X. "Would you like to open this type of a file with that application you downloaded?".

You would likely want different rules for Calls versus Instant messages.

Posted November 10, 2010 at 6:29 PM | Permalink | Reply

Foo

Am I missing something here? Latest iOS and latest version of Skype does not automatically initiate a call when skype: and or call: URIs are clicked, entered into Safari. Instead a UI requiring interaction is presented.

The Protocol handler is registered on OS X, iPhone IOS and Windows systems at install, for all browsers - Windows also includes the Skype4COM ActiveX control exposing a feature rich API with it's own security model.

Again on these platforms user interaction is required at the very least in order to authorise the inter process interactions and can be overridden with a don't prompt me again user opt out.

Posted November 12, 2010 at 11:48 PM | Permalink | Reply

John

I have a web app for iphone to do speed dial (www.iphone-speeddial.com) if anyone interested) and I tried to implement this as a feature. Interestingly it doesn't work when you save the page on the homepage. I'm base64 encoding it and locally storing it so I'm not sure if that's what changes it. If anything I think it should be the other way.

Posted November 29, 2010 at 3:46 PM | Permalink | Reply

UI Spoofing Safari on the iPhone

[...] second in a series of guest posts from security researcher Nitesh Dhanjani. His first post was on Insecure Handling of URL Schemes in Apple?s iOS. Nitesh will be giving a talk on &#8220;Hacking and Securing Next Generation iPhone and iPad [...]

Posted April 02, 2012 at 3:56 AM | Permalink | Reply

Art

it seems Skype have since addressed this. it will now come up with a "Placing your call " dialog box allowing the user to either proceed or cancel.

Post a Comment






Captcha

* Indicates a required field.