Why Safari got Nitro and Web Clips and UIWebView didn't

As we posted the other day, while Safari in iOS 4.3 got a huge speed boost thanks to the Nitro JavaScript engine, asynchronous mode, and HTML 5 caching, bookmarking a site to the Home Screen (Web Clips) that launch in full-screen mode, or browsing inside an app (UIWebView) didn't. That meant, while web apps on the home screen and web pages embedded in apps were as fast as they were in iOS 4.2, they weren't as fast as Safari in iOS 4.3.

The technical reason for this is because Nitro is using Just-in-Time (JIT) compilation. Daring Fireball says:

A JIT requires the ability to mark memory pages in RAM as executable, but, iOS, as a security measure, does not allow pages in memory to be marked as executable. This is a significant and serious security policy. Most modern operating systems do allow pages in memory to be marked as executable β€” including Mac OS X, Windows, and (I believe) Android1. iOS 4.3 makes an exception to this policy, but the exception is specifically limited to Mobile Safari.

It’s a trade-off. Most OSes allow marking memory pages as executable for performance reasons. iOS disallows it for security reasons. If you allow for pages of memory to be escalated from writable to executable (even if you require the page be made permanently read-only first), then you are enabling the execution of unsigned native code. It breaks the chain of trust. Allowing remote code to execute locally turns every locally exploitable security flaw into a remotely exploitable one.

So if you load a page in Safari or have a Home Screen bookmark that launches into Safari, you get Nitro because Apple trusts Safari (which given how big an attack target Safari has is... interesting.) If, however, you load a page in an app using UIWebView you get the old JavaScript engine because Apple doesn't trust that app. If you launch a Home Screen bookmark that includes specific code for full screen mode, Safari doesn't pick it up but it opens in Web.app and -- for some reason -- Apple doesn't trust that either (yet?).

WebKit2 -- which iOS 4.3 doesn't seem to be using -- could address this because it uses split processes built into the frameworks but there's no word on when or if Apple will implement it in iOS. (It's reportedly implemented in Mac OS X Lion beta.)

So no conspiracies, just the usual trade offs between security and convenience and the limits of Apple's resources to get everything done all at once. (We won't put the pitchforks and torches away altogether, however, and Web.app gets Nitro, and everything gets WebKit2.)

[Daring Fireball]

Have something to say about this story? Leave a comment! Need help with something else? Ask in our forums!

Rene Ritchie

EiC of iMore, EP of Mobile Nations, Apple analyst, co-host of Debug, Iterate, Vector, Review, and MacBreak Weekly podcasts. Cook, grappler, photon wrangler. Follow him on Twitter and Google+.

More Posts



← Previously

Wi-Fi-only iPad 2 captures cleaner audio than AT&T and Verizon 3G models

Next up β†’

Daily Tip: How to clear your browsing history in Mobile Safari

Reader comments

Why Safari got Nitro and Web Clips and UIWebView didn't


Most of my web browsing is actually done with the UIWebView component, from inside other apps. I rarely use Safari by itself, and for general browsing I use an alternative browser (Atomic or iCabMobile), which also suffer from this limitation. I really hope Apple plans to play fair and update that component soon.

What? When I upgraded to iOS 4.3 it didnt add a second core to my iPhone. I must have done it wrong.

I don't understand Gruber's argument. Why trust Safari and not UIWebView?
Wel, I undertand his argument, he has to defend always Apple.

That's the part that makes little sense. Safari is a much larger attack vector, and one without any App Store hoops to hurdle. The security excuse does not pass the smell test.
That doesn't mean Apple is twirling their mustaches as they tie UiWebView to some metaphorical train tracks. Most likely, this is a bug - or a feature they could not get by 4.3 release, and they will address it soon.
At least, I hope so.

It makes more sense to trust safari because it is there own app. Why trust third party apps and also it gives you more motive to use safari.

Safari ad a container for web apps is exactly the same as UIWebView. Can you explain me which difference there is on executing Facebook from Safari and a HTML app inside UIWebView?
And UIWebView is not an Apple app?

Gruber's argument is that the JavaScript improvements in Safari require the use of a JIT (just-in-time compiler). The JIT converts JavaScript into native code that the iPhone's CPU will execute directly. As Gruber explains, for security reasons iPhone apps are not normally allowed to execute data that they have generated themselves. Thus any third-party app using an embedded UIWebView will not be able to make use of the JIT.
Gruber suggests that Apple has lifted the restriction about executing data just for Safari, so that it can take advantage of the JIT - the idea being that as Safari is an Apple-implemented app they feel safe about lifting the restriction. He also says that it's quite likely Apple is working on a secure solution to allow all apps to make use of the JIT, but these things take time!

And is an argument that doesn't make sense. There is exactly the same security concerns on uiwebview and safari, they both execute THIRD PARTY code.

The issue is not about the dangers of executing third party JavaScript code, which has always been possible in UIWebView. The concern is about lifting the general restriction about allowing data to be marked as executable, which is a prerequisite for using Nitro. A consequence of lifting the restriction is that any third party app will then be able to generate/download some data and execute it natively as ARM code - currently this is not possible: the only ARM code that gets executed in a third party iPhone app is code that is submitted to Apple for approval.

Although there is a case to answer as to why full screen web apps, which apparently are executed not by Safari but by another Apple-written app called Web.app, do not benefit from Nitro. Maybe this is just an oversight. Certainly the security implications associated with allowing third party apps with embedded UIWebViews to access Nitro do not apply to Web.app any more than they apply to MobileSafari.app!

"And how an app can donwload an execute ARM code when JIT is enabled on UIWebView?"
Because for JIT to be enabled for UIWebView, the process running the app that's using UIWebView has to have permission to execute data as code. This permission is on a per-process basis, not a per-library basis. This means that you can't restrict the ability to execute data as code just to the UIWebView component, instead the whole app gets the ability to execute data as code - which is what Apple is trying to avoid.

I thought that "web-apps" are just web book marks saved on the homepage and they open Safari and are the sameas a mobile site.?

How silly. Even a third grader sees the falsehood of this logic. Hey Gruber, IT'S THE EXACT SAME JAVASCRIPT! If it can compromise one, it can compromise the other.
Course, as usual, the Gruber hypocrisy knows no bounds. I remember the pains he went to to defend Apple's lockout of Flash apps and other frameworks, then when Apple later did a 180 about face, not even a hint of retraction from his cheerleader blog.

The security risk is not to do with JavaScript. As others have explained, it's to do with the Nitro JIT required that the process be allowed to execute data, i.e. the app can generate some native ARM code that the iPhone's CPU executes directly. Apple's trusts Safari to generate safe native code as they are in charge of it. If other apps were allowed to use Nitro (i.e. when the embed a UIWebView component) they'd also have to have permission to execute code as data, and this results in a potential security nightmare.