Showing posts with label XSS. Show all posts
Showing posts with label XSS. Show all posts

Sunday, February 09, 2014

JavaScript Off for iOS

While testing UIWebView on iOS I found out there is no option to turn off JavaScript for web content. Initially I tried to use HTML5 "sandbox" attribute do achieve this, but in practice Content Security Policy is a much more flexible solution. Injecting CSP headers into NSHTTPURLResponse seems to work even for file: and data: URL schemes.

A sample application testing above solution is available on GitHub, and a similar solution has recently made its way into Onion Browser as an experimental feature. I am looking forward to see how it's going to work in practice.

On a side note, Quick Look is another solution if you need to load a single HTML document with JavaScript turned off.

iOS UIWebView baseURL

UIWebView is one of the most popular components in Cocoa Touch library. It can be used to easily embed web content into iOS applications and - of course - to equally easily introduce Cross-Site Scripting vulnerabilities.

When loading content into webView on iOS, a programmer can choose one of three methods:

  • – loadData:MIMEType:textEncodingName:baseURL:
  • – loadHTMLString:baseURL:
  • – loadRequest:

Did you notice baseURL in the first two? This inconspicuous parameter is quite important when dealing with XSS.

Same Origin Policy works a bit different in iOS than we're used to in desktop browsers, namely file: and applewebdata: URLs have complete cross-origin access to any web resources, in addition to local file access. This means if you save untrusted HTML document locally and then call loadRequest method to load it from its file:/// path into UIWebView, you're simply creating a universal Cross-Site Scripting vulnerability. This document can now read all cookies stored by the application, call JavaScript across domains (including your corporate intranet), and do all that stuff Same Origin Policy usually prevents.

Alternatively to loading untrusted local file with loadRequest, you may first read its content and then use one of the two remaining methods: loadData or loadHTMLString. Unfortunately, by default UIWebView content is loaded with file/applewebdata privileges. This is where the baseURL comes in handy. Simply set the baseURL to "about:blank" URL and Same Origin Policy will prevent cross-origin access (as it probably should do by default, Apple?).

Of course this won't be enough if a webView contains sensitive data and untrusted content at the same time, or if you bridge JavaScript with Objective-C through special URLs catched in webView:shouldStartLoadWithRequest:request. In such cases you should remove all XSS vulnerabilities from your application, one by one.