Hacker News new | past | comments | ask | show | jobs | submit login
RTFM 0day in iOS apps (algorithm.dk)
186 points by algorithm_dk on Aug 21, 2014 | hide | past | favorite | 58 comments



This is not the default behavior for a UIWebView. It relies on a practice that is very common among developers of iOS apps with web content.

Specifically: every click/interaction that loads content in your custom web view sends the webView:shouldStartLoadWithRequest:navigationType: message to your web view delegate. Without implementing that method, clicking a tel: link will prompt first. However, many apps throw some logic in there to detect any URI schemes that don't match the standard HTTP/HTTPS schemes used in normal websites, and trying to do something "nice" for the user, they handle requests for those URIs by calling:

[[UIApplication sharedApplication] openURL:request.URL];

This is a reasonable thing to do (outside the context of tel: links) because it allows the app to spawn an external app for custom URIs.

Therein lies the problem: not that UIWebView opens tel: links without prompting (it doesn't), but that many app developers are just trying to improve the inter-app experience, and unknowingly open tel: links directly with that openURL: method.

EDIT: Just my opinion, but I think it's actually pretty cool that Apple gives developers the ability to dial phone numbers without an extra prompt. It makes third-party contact/phone apps much more useful (imagine having to confirm every phone number to dial after tapping the contact in the built-in phone app). In a way, this is the kind of trust / freedom that iOS developers rarely enjoy without a fight. It's just unfortunate that in this instance, it also happens to be very easy to overlook this pitfall when implementing web view logic that handles non-http links.


While tel:// URLs open the Phone app without any prompt, there's also a telprompt:// scheme which opens the Phone app with a prompt. As an app developer, would you ever want to use the latter scheme instead of the former? Turns out, yes, you would.

The advantage that you get with telprompt:// is that, once the call finishes, the user comes right back into the app that initiated the call. With tel:// that is not the case.


Indeed I almost always use telprompt:// over tel:// for exactly that reason. It's usually better to bring them back into the app when the call finishes.


Seems infinitely more reasonable to have the default be a prompt, and to have to explicitly enable "auto calling". People making a contacts app for example would immediately notice the prompt and rectify it. Meanwhile everyone else can remain blissfully ignorant of the tel: scheme.

On the other hand, with this system, every single app that ever uses a web view has to somehow magically divine that this could be an issue. The UIWebView docs certainly don't warn you about this. So what, is the expected behavior is that if you ever use a WebView in your app you should read every RFC on the planet in case there's some weird edge case like this? Maybe instead of creating systems that require careful developers we could try creating systems that work well by default and need you to explicitly turn on dangerous features like this.


Well, yes the prompt should be default. However, when I use a WebView in my apps I always consider the URIs in links to be potentially malicious.


Strange design choice on Apple's part. Having not read the documentation, my expectation would be that native buttons don't require a confirmation, but links coming from a webview do. It would have to provide an option to suppress the popups in use-cases where the developer is building their app in a webview, but if you're already jumping through all of the hoops for that sort of cross platform development, one more configuration to set isn't a big deal.

I'd blame Apple just as much as the devs. They made a choice to be insecure by default in a situation when a majority of developers are going to assume it functions like the rest of the OS does. Web views in any app ought to behave like Safari by default.


This is true, both bad defaults and people not reading documentation. It's just like mongo that start by default with remote access enabled and no password - Shodan "mongo" and you will find thousands of live, not protected databases.


I would think a more likely to be exploited use case would be to find the telephone number of celebs. Send the celebrity some specially crafted message on FB or twitter with a good mix of social engineering and you should be good to go (provided they are on their phone when they view your message)


Absolutely an exploitation technique. Or you can facetime them instantly and catch a photo of them in pijamas!


Hi guys,

I just did a talk during BSidesLV on the subject of URL Schemes and dangerous implementations.

For those who want all the details:

http://youtu.be/rJroherlZVo?t=1m33s

For those who want to skip explanations on how they work and see the bad examples, auto skipping about 10min:

http://youtu.be/rJroherlZVo?t=10m24s

One example that I have in there is Yo. Yo will automatically Yo someone on your behalf. So if an inline frame has yo://gepeto42 (basically), and you have Yo installed, I have just "de-anonymized" your Yo account as you browsed my website (or any page where I could inject that iframe). A good tip on where to find out about those is to buy Launch Center Pro and to extract the plist it has. This has info about hundreds of iOS apps and how their URL Schemes work.

Happy hunting.


Great work man! I'm glad we can bring attention to security issues. Maybe we could work together.


> When a user opens a URL with the tel scheme in a native app, iOS does not display an alert and initiates dialing without further prompting the user.

What is the justification for this behavior? Why should the web browser open a prompt but not other apps?


Because the apps can initiate a call by just pointing a webview at tel:0000. Another reason is hybrid apps, imagine a contact hybrid app running in something like PhoneGap. You want to click a button and call right away without the phone asking you to confirm your action.

I'm not saying that Apple's design is good, but it is documented.


That was my thought as well. I'm sure the decision was made to connect as seamlessly as possible, without the user having to stop and click a dial confirmation.


I imagine the other apps are responsible for their behavior. The browser gets special locking down because practically anyone can end up sending you anything.


Other apps can too. You have to use telprompt instead of tel in the URL scheme.


Why was this information immediately released/zero-day'ed? Is this method ignoring responsible disclosure or am I missing something?

FB, Google, and others all pay for bugs such as these, so even monetarily, it doesn't make sense to just release it to the public immediately. Again, this is assuming these bugs were not disclosed previously to companies affected.

edit: clarification


It is not a 0day in the traditional meaning, it's a simple <did not read the manual> and <bad defaults> case. On the other hand I've been waiting to get on Apple's HoF for two years now, reporting cross-site scripting bugs and even a sqli - yet I'm not there. Apple is not getting any responsible disclosure from me.


So are you investigating security to find security holes or to be on the hall of fame of cool kids?

This affects users much more than it affects Apple.


Then go and tell Apple.


I understand not reporting it to Apple, in their case they have basically disclosed the issue to anybody that read the manual (and they don't have the bug in their apps). I was primarily referring to the major players who do have the bug and whose primary responsibility the bug is.


I can't do responsible disclosure when there are tens of thousands of apps using webView. The number of vulnerable apps is way too high for any kind of responsible disclosure.


You could have told Apple. They could fix this in iOS, blocking the apps via a software update.

If it was me, I would have notified Apple and all of the companies who have bug bounty programs.


Apple knows. Look at the security content of iOS 7.1.

http://support.apple.com/kb/HT6162

I reported CVE-2013-6835. They fixed Facetime-Audio from Safari, but not from other browsers (yet?). This is quite a wide issue. I do not think letting every individual developer know is feasible. I did it for a few bad issues, but there's a limit to what can be done.

And a lot of these can be found in a matter of minutes anyways.


It might not be feasible, but why not if they might pay you money for it?


Please don't purport to be the authority on what is and is not responsible. This term was rejected by the industry for a reason.


With all due respect, I did not purport to be any kind of authority. In fact, I asked a question, assuming the knowledge of HN would answer the question if my understanding was faulty.


You're saying that it's the app developer's fault that they haven't read all of the iOS developer documentation before opening webpages in a web view (rather than just the web view documentation)? That seems ludicrous.


Well done I myself enjoy reading RFC's, but have yet to create something as crafty as this. Good work! Does not work on Android 4.4.2 requires application selection and then brings you to dialpad.


Thanks a lot! I asked a friend to test it for me on android (wondering if it works) and I was glad that it doesn't. On Android it fills the phone number for you and lets you push the call button, which seems to me a much saner design.


Forgot to mention: Tested via google+ and hangouts with above mentioned android version. No FB acccount or messenger on mine to test that app so cannot speak to it but it seems the method of mitigating this attack is built in to Android.


It is. There's a separate permission for being able to initiate calls without prompting, and a separate intent -- most apps should use ACTION_DIAL[0] (which prompts), while apps with the right permissions may use ACTION_CALL[1], which doesn't.

There's yet another intent for dialling emergency numbers without prompt, which is reserved for system use -- non-system apps can only dial emergency numbers indirectly using ACTION_DIAL.

[0]: https://developer.android.com/reference/android/content/Inte... [1]: https://developer.android.com/reference/android/content/Inte...


There have been vulnerabilities related to tel: URIs before, in particular this one that let you factory reset Samsung phones.

http://www.techhive.com/article/2010562/reported-android-fla...


I disagree that it's not Apple's fault. This is a violation of the "principle of least surprise." When I drop a web view into my app I am not expecting web pages to be able to do much other than just be web pages. I'm certainly not expecting them to be able to dial the phone without prompting.


The article is misleading, if you do nothing your webview won't open any phone call. You have to implement a specific method to intercept links and explicitly open them in the device.

see `- (BOOL)webView:(UIWebView )webView shouldStartLoadWithRequest:(NSURLRequest )request navigationType:(UIWebViewNavigationType)navigationType` method in official UIWebViewDelegate reference[0]

[0]https://developer.apple.com/library/ios/documentation/uikit/...


Reminds me of the auto-reset Android bug that utilized a tel: URI that auto-dialed: http://gizmodo.com/5946334/samsung-security-bug-can-wipe-out...


Regarding your link, I'm currently on a computer without AdBlock for the first time in a while, and when I went to the gizmodo link it popped up a video ad I could skip in 5 seconds to continue reading.

Is this a standard thing? Are there really sites, especially one as big as gizmodo, that think it's a great idea to not let people view a few kilobytes of text before burning through any data limit they have with some mandatory video I don't care about?

Now I remember why I installed AdBlock.


Yes, it is standard practice now for Web designers to completely disregard more correct practices for their websites. Welcome to the twenty-first century...


I'd call this bad design on Apple's part -- they should require the application to explicitly define a custom handler or fall back to default (secure) behavior. Yes, it's documented, but I'd call it a design flaw.


Undoubtedly a poor design choice, I appreciate that you bring some attention to it.

  Facetime calls are instant. Imagine you clicking a link, your phone calls my (attacker) account, I instantly pick it up and (yes) save all the frames. Now I know how your face looks like and maybe where you are. Hello pretty!

  Yes, it works. I tried.
Can you please provide some evidence that this is practically possible? Last time I used Facetime it took quite some time before the connection was established.


I did my test on WiFi which results in almost instant calls for me. Set your computer to catch the facetime call and answer it automatically (check this: https://github.com/PaperCutSoftware/teleportme/blob/master/t...). Capture your screen continuously and if you might get the first frames of the call. It's all about what people do when their phone starts calling by itself. Most people freeze which results in a successful attack.


Being a bit pedantic here, but shouldn't it be specified as a URI, "tel:0000" not a URL-ish "tel://0000" with 0000 as the authority?


There was a talk at BSidesLV called IOS URL Schemes omg:// http://bsideslv2014.sched.org/event/21c84fe90196be5a475f6b33... You'll probably want to watch this on Youtube: https://www.youtube.com/watch?v=rJroherlZVo


There are a lot more security threats. My startup's URL reputation lookup service is being integrated with one of the biggest app platforms to help developers build security into apps. There are so many security threats that come with the standard WebView - mostly because I'm confident Apple and Google didn't think about how they could be used today.


[deleted]


Yeah, I think I disagree with the author. Unless someone can think of a reason it should be like this, I think it's Apples' fault. If there's a reason to allow no-confirmation telephone or facetime initiation, they should make it an option on WebView.


I never said I agree with Apple, I think it's a extremely bad default.


> I never said I agree with Apple, I think it's a extremely bad default.

You did say this, though, which is what GP is responding to:

> Who did the mistake?

> Well Apple did not. People didn't read the documentation at all.

If the default is this bad, having it in the documentation is not an excuse.

Especially since this is in the documentation for handling phone links, and the exploit explicitly affects apps that do not utilize/customize this functionality.

You can't say it's the developer's fault for not reading the documentation for a feature they never wanted to use in the first place.


[deleted]


Send it using the Facebook Messenger app or GMail app. The fault is in the apps not in the system. Your code is correct.


It works - thx!


Chromium Bug Thread about this: https://code.google.com/p/chromium/issues/detail?id=329259

"In practice, the closest to 'malicious' use I've seen the redict-to-app-store-from-ad case"


I completely disagree that Apple is not at fault here. It should always prompt, end of story. More importantly though is that the devs at FB, Google, etc, likely saw how it worked in mobile Safari and, wrongly, assumed it would work the same in a webview. Why have the inconsistency in an a tag?


There are legit reasons to want to dial without a dialog. Apps like launch center pro, or a 3rd party contacts app. I agree the default should be prompt, but an option to disable that is definitely beneficial to users most of the time.


I agree, most people wouldn't here because t h i s i s h a c k e r n e w s.


well Apple did not learn from their previous mistakes and from the Android related Tel+USSD issues - http://www.securityfocus.com/archive/1/504414/30/0/threaded http://www.osvdb.org/show/osvdb/85806 . But I did follow responsible disclosure procedure before going to public and informed Google, Samsung. I hope he did the same :/


this may be off topic, but I don't recognize some of the UI elements(battery life, signal strengh, etc) in his screen shots, and I can only assume that is an iOS8 beta. Isn't he breaking his NDA by showing off an unreleased OS? Security hole or not?


It looks like a jailbroken iPhone, but also Apple have relaxed their NDAs regarding beta versions.


exist any solution to send URL with command "Send iMessage "text" to "user" ?! automaticly without tap to "send" ???


I tried this but was unable to reproduce it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: