Showing posts with label UXSS. Show all posts
Showing posts with label UXSS. Show all posts

Saturday, June 21, 2014

Browser Shredders Challenge #1

For some time now I haven't succeeded in triggering password autofill in any iOS browser from a downloaded HTML file (which would allow another easy way to steal passwords). There are no Same Origin Policy constraints for local HTML files, so it seems easy to just open the target website and read the password, but there are some problems:
- password autofill does not work in cross-domain frames in iOS browsers based on UIWebView
- calling window.open() overwrites the calling window, so I cannot control content while having the target website open
-  I didn't find any other way to set location.host or mainDocumentURL.host to target domain while still controlling the content

I guess there may be some solution which I overlooked, so here is the challenge for you:



A sample application with the code above - which you may run on iOS simulator - is available on GitHub. The task is to prepare a local HTML file (/tmp/challenge1.html) in such way that "You completed the challenge" line will get executed.

There is no reward unfortunately, apart from a humble "thank you" during our SyScan360 talk :-)

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!