A couple months ago, while attending the recent iPhoneDevCamp 2, I had the opportunity to speak with a number of developers who were doing JavaScript development on the iPhone.
One developer, Wayne Pan, showed me this weird bug that he kept encountering: He was using CSS Transforms to change the positioning of some elements that were contained within an iframe - but when he did this the elements would 'jump' outside the iframe and overlay its contents over the parent page.
I asked him to prepare a simple test case for me so that I could explore it further - anything jumping outside of an iframes' confines is a huge no-no in browsers - it could lead to a form of a Clickjacking attack.
I did some more testing - I needed to confirm two things:
Could a CSS transform, in fact, position an element outside of an iframe.
Could one interact with the items that were placed outside the iframe.
I created two tests - one which utilized a link that I wanted to spoof and another that had a password input that I wanted to spoof. Both had the same basic principal: Assume that an iframe on a page (maybe a banner ad?) was malicious and wanted to trick the user into providing information, or visiting a certain page, when they interacted with the element's contents.
The contents of the iframe'd page looked something like this (this is the link spoofing case):
This is what the pages should look like (or look similar to them, at least) in MobileSafari - if the bug did not exist:
But this is what it looked like on the iPhone OS 2.0 (no other WebKit engine was effected):
Note that the iframe banner ad isn't even visible when this bug is in play: The shifted iframe contents have completely overwritten the parent page. The user is oblivious to what is happening: The URL looks correct - and so does the link/password input - but it's all being spoofed by the malicious iframe.
Interaction with the elements yields the spoofed results:
So while it's obviously possible to override the complete pages' contents it's important to note that the contents shifted outside the iframe are not able to be interacted with -- only the contents that still remain within the confines of the iframe boundaries. This makes it an 'imperfect' attack but certainly one that is still very potent. A smart phisher could easily work some magic to trick the user.
I should note that after I discovered all of the above I quickly submitted my findings to the Apple Security team. They deemed it to be very important and asked me to not write about it - which I did.
The other day they finally released iPhone 2.2 which included a fix for my specific issue.
CVE-ID: CVE-2008-4232
Available for: iPhone OS 1.0 through 2.1, iPhone OS for iPod touch 1.1 through 2.1
Impact: Websites with embedded iframe elements may be vulnerable to user interface spoofing
Description: Safari allows an iframe element to display content outside its boundaries, which may lead to user interface spoofing. This update addresses the issue by not allowing iframe elements to display content outside their boundaries. This issue does not affect systems prior to iPhone OS 2.0 or iPhone OS for iPod touch 2.0. Credit to John Resig of Mozilla Corporation for reporting this issue.
It's great to see a fix for this problem come about quickly and efficiently - and if you're still running an old version of the iPhone OS please be sure to upgrade!
I've been watching, with interest, developers create new applications for the iPhone. Owning one myself - and being knowledgeable in JavaScript - I've been wondering what options there were for creating downloadable JavaScript applications or the iPhone. In doing some research I found a number of solutions, some simpler than others, some requiring more knowledge of Objective-C than others.
Before looking at the options I should note that given the requirements of the platform if you're really serious about getting in to iPhone development you should learn Objective-C. None of the options appear to provide the full range of functionality that a normally-written application would.
This was an early entry to the JavaScript iPhone application market - arriving back in 2007. It requires a Jailbroken iPhone (likely running version 1.1 of the Operating System).
JiggyApp provides a full API for developing an application - apparently separate from most of the typical APIs. Arguably, though, the code ends up being relatively usable.
Plugins.load("UIKit");
var window = new UIWindow( UIHardware.fullScreenApplicationContentRect);
window.setHidden(false);
window.orderFront();
window.makeKey();
window.backgroundColor = [0.8 , 0 , 0, 1];
JSCocoa is a full bridge that maps Cocoa development into JavaScript (instead of the typical Objective-C/Cocoa mapping). The result ends up working in both OS X and on the iPhone.
It's a pretty-clear port of Objective-C style and mannerisms but with a JavaScript syntax. Note some of the differences:
Right now it seems like JSCocoa is more usable for developing OS X applications but the progress moving forward is certainly promising.
"Applications" in MobileSafari
While it's not, technically, a true iPhone application one option is to adapt your existing web applications to be used in a more application-centric manner.
Apple provides a number of tips for improving the style of your web application. The most important points of which are:
Providing a tray icon for the application (to be used when the user saves it).
Providing a full-screen view of the application (with no MobileSafari toolbars showing).
This will give the full appearance of a regular iPhone application (after using some more styling and setup from iui, or similar).
The next step to making your iPhone web application more native-like is to tap into some of the underlying native APIs. One recent release that will help is that of PhoneGap.
PhoneGap is an application that exposes a few JavaScript APIs to pages running MobileSafari. Right now this includes Geolocation and access to the Accelerometer.
Geolocation:
getLocation();
function gotLocation(lat,lon){
document.body.innerHTML = "latitude: " + lat + " longitude: " + lon; }
They're also working on access to the camera, sound, and vibration tools of the phone.
WebTouch
The other day "Dr Nic" wrote up an article on how he had used a WebKit instance (along with HTML, CSS, and JavaScript) to render a portion of his iPhone application.
I contacted him about the project and wondered if he'd be willing to provide some of the code that backs it. Written up by his co-worker at Mocra, Anthony Mittaz, the result is called WebTouch.
Right now it's just a zip file of sample code but hopefully it'll be expanded at some point.
It's really simple and gives you a good entry point into the world of hybrid HTML/CSS/JavaScript/Objective-C/Cocoa development. If you've been interested in Objective-C this might make for a good starting point, as well.
Bonus
While this isn't something that you can actually use, I think it's pretty cool. This guy ported my Processing.js work to the iPhone, writing his own Canvas implementation using OpenGL ES hooking in to SpiderMonkey.
There are a lot of options available for the discerning JavaScript developer - the most promising of which is, I think, WebTouch. It's pretty obvious that in order to be able to build the best possible iPhone application you would have to know Objective-C. Having a clear path, paved with JavaScript, to that end result should be any JavaScript developer's goal.
The other week I went to the Boston iPhone Tech Talk and took a bunch of notes. I thought everyone would be interested in what they had to say as its quite relevant to Mozilla's upcoming mobile efforts, and the browser space in general. Let me know if anything needs any, additional, clarification.
Notes:
There was a lot of JavaScript hate by attendees ("blah blah... GWT is the only thing we trust... blah blah JavaScript is a stupid language..."). Not really surprised. Generally, these are Mac application developers by trade and the Open Web, by comparison, is frustrating and limiting.
There was strong promotion of web standards, down play of plugin (Flash, Silverlight, Java Applets) dependencies.
They recommended optimizing your page according to the following points: Scales for readability, minimize pan/zoom, finger friendly, and tuned for wireless. That translates to: Use clear type and logical page layout, reduce the height or width of the page to better fit within the screen, make your links and inputs large (to handle the large "mouse pointer"), and make liberal use of caching and gzip. All of these are good points to encourage within the web, in general.
Pages that are marked up with XHTML Mobile or are on a .mobi domain are handled specially (they're shown unmodified - assuming that the developer has already optimized the page for a mobile device appropriately).
There are some, very interesting, limitations to pages; and the browser, in general. For the most part this shouldn't effect many sites (especially considering that plugins don't run). I've noted the JavaScript-related ones:
10 MB JavaScript object allocation
5 second JavaScript execution limit
XHR not counted to JavaScript execution time (async or sync)
Scripts may be paused (Inactive window, Safari not active)
Scripts are not paused while a Quicktime movie is playing
Maximum 8 windows open at a time
I found it to be interesting that JavaScript execution was pausable. Thus, if have a game running in one window and go to another, the game (presumably, written in JavaScript) will be paused until you come back to it. This model is akin to what they currently do with Dashboard widgets (which are, also, HTML/CSS/JS and are paused until you view them).
It's important to note that, not only, are you not able to have more than 8 windows open at a time, but you don't have control over windows that you open. There is no such thing as a popup or modal dialog. Nor are there tabs to browse through the open windows (You have to navigate to a separate view where you browse thumbnail views of the sites). I've been trying to decide if this is more-tabbed-like or less-tabbed-like because of how it's designed (e.g. one could argue that having modal popups breaks the tabbed model), whereas not actually having access to tabs (or information about the tabs that you open) is very limiting.
Only three dialogs are allowed: alert, confirm, and prompt. They are all highly styled and consume a large portion of the screen when they appear.
Interacting with form controls is highly unique. When you do so you are placed into a separate editing/manipulation mode laid on top of the browser itself. This is indicative of the larger theme in the browser: They consistently push the user into a separate pane to deal with specialized content. I think that this is an incredibly interesting development and - quite possibly - an optimal way of dealing with "non-native" browser content.
For example, Excel, Word, PDF, and Quicktime content are all handled natively by the browser - and are shown in separate, specialized, views. (Videos are especially interesting - the whole browser is hidden and is replaced with a completely-tailored UI that is optimized for viewing movies.) I was hugely impressed by this set of features and I really think that this is a huge step for a browser to take. Mozilla is starting to do this with the new video tag, but providing means for handling common documents might be interesting as well.
They include a fully standards compliant version of Canvas - they recommend using it, highly. In fact, they recommend using things like border-image, border-radius, and Canvas to remove the need for extra markup or images.
There is no way to completely emulate the iPhone outside of the iPhone itself (e.g. no desktop iPhone browser - even though there's Webkit/Safari - it's not completely the same).
Webkit's new Element Inspector is very, very, nice. Heavily inspired by Firebug, but with the trademark Apple UI touch. They have a CSS/Stylesheet browser (like Firebug) but they also include the default User Agent Stylesheet (which is immensely useful).
To allow the user to have control over page scaling they define a custom meta name/content that you can use:
<meta name='viewport' content='width=320'/>
The possible values for it are as follows:
width=320 (how wide to start the viewport at)
initial-scale=1 (default dimensions)
minimum/maximum-scale (limits user/auto scaling)
user-scalable=yes/no (Allows/prevents zooming via double-taps)
When the user zooms in on a portion of the page, you can adjust how large/small the font size should become with a custom CSS property:
-webkit-text-size-adjust: none
none (font size doesn't grow larger)
auto (the text grows larger)
200%, the text grows even larger
They also publish their own, custom, event and window property to let the user know about the orientation to which the iPhone is rotated, it can be used like so:
There is no concept of hovering (or, really, mouse move events in general - drag/drap isn't possible).
There are no multiple selects. All multiple selects are just treated as single selects.
There is no way to detect which type of connection that you're on (Edge vs. Wireless) and to serve content based upon it. The one catch is that you're able to do it with Quicktime (serving different types of movies) but not with normal web content.
Finally, they're very interested in getting a public sync schema for bookmarks - one that works across all browsers (easily synchronizing Firefox with Safari with iPhone Safari, etc.). Apparently they've contacted Mozilla in the past about this, but I'm not sure to what end this has led.