
RTFM 0day in iOS apps - algorithm_dk
http://algorithm.dk/posts/rtfm-0day-in-ios-apps-g-gmail-fb-messenger-etc
======
dperfect
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.

~~~
chaitanya
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.

~~~
kenrikm
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.

------
tolmasky
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.

~~~
klodolph
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.

------
wlesieutre
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.

~~~
algorithm_dk
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.

------
DanBlake
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)

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

------
gepeto42
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](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](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.

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

------
username
> 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?

~~~
algorithm_dk
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.

~~~
aye
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.

------
lukeqsee
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

~~~
algorithm_dk
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.

~~~
lukeqsee
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.

~~~
algorithm_dk
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.

~~~
eyeareque
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.

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

[http://support.apple.com/kb/HT6162](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.

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

------
yincrash
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.

------
sprkyco
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.

~~~
algorithm_dk
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.

~~~
sprkyco
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.

~~~
andrewaylett
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...](https://developer.android.com/reference/android/content/Intent.html#ACTION_DIAL)
[1]:
[https://developer.android.com/reference/android/content/Inte...](https://developer.android.com/reference/android/content/Intent.html#ACTION_CALL)

------
api
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.

~~~
woogle
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/...](https://developer.apple.com/library/ios/documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html)

------
thom_nic
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...](http://gizmodo.com/5946334/samsung-security-bug-can-wipe-out-your-
galaxy-phone-updating)

~~~
ntumlin
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.

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

------
Tloewald
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.

------
michaelmcmillan
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.

~~~
algorithm_dk
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...](https://github.com/PaperCutSoftware/teleportme/blob/master/teleportme.command)).
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.

------
adam-f
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?

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

------
paulfwalsh
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.

------
gepeto42
Chromium Bug Thread about this:
[https://code.google.com/p/chromium/issues/detail?id=329259](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"

------
losingthefight
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?

~~~
kennywinker
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.

------
raviborgaonkar
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.securityfocus.com/archive/1/504414/30/0/threaded)
[http://www.osvdb.org/show/osvdb/85806](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 :/

------
S_A_P
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?

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

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

------
lsv1
I tried this but was unable to reproduce it.

