Saturday, June 21, 2014

Exploring and Exploiting iOS Web Browsers - local HTML files

A quick summary of the possible methods for preventing UXSS when loading untrusted local HTML files into iOS UIWebView:

1. Load as plain text
This would probably break the planned functionality of the application, but you can always decide to use loadData method with mimeType text/plain and forget about all the HTML problems.

2. Content-Security-Policy headers
By using NSURLProtocol and connection:didReceiveResponse you can inject CSP headers to block JavaScript execution (also for file: URIs).
The only application implementing similar solution that I know of is currently Onion Browser. Cure53 found a way to bypass CSP in this browser, but this was due to the fact that file and data URIs were explicitly skipped before injecting the headers (it is a bit misleading that you can inject HTTP response headers for documents that are not requested through HTTP, but it really works).

3. HTML5 sandbox
Using iframe sandbox instead of CSP seems potentially less prone to bypasses, but it is a bit less convenient to implement. You first use loadHTMLString with baseURL=nil and a sandboxed iframe in content, then you run stringByEvaluatingJavaScriptFromString to point the iframe to the file you want to load.
This way your JavaScript can operate on the loaded file, but the loaded file cannot execute JavaScript (unless you allow-scripts or allow-top-navigation; any of them gives UXSS again).

4. Less-privileged baseURL
This is the most common solution used by many applications. Most of them use baseURL pointing to some domain related to the application, but an even better solution is to use about:blank. I already wrote about it before. This does not prevent JavaScript from running, but restores Same Origin Policy constraints.

Do you know other solutions? Or maybe you know how to break these above? Comments welcome!

No comments:

Post a Comment