Skip to content

Back to the catalog

Android security checklist: theft of arbitrary files | Oversecured Blog
oversecured.comarticle

Android security checklist: theft of arbitrary files | Oversecured Blog

Oversecured's Android security checklist on arbitrary file theft from an app's private storage. It covers implicit intents (PICK, GET_CONTENT) returning file:// or content:// URIs, SEND/SEND_MULTIPLE share activities, exported and non-exported FileProviders, path traversal via Uri.getLastPathSegment, WebView, and local NanoHTTPD servers. Each case has vulnerable code, an attacker PoC and fixes such as /proc/self/fd path checks and narrow files-path entries.

TL;DR Lists the common ways Android apps leak private files via intents, content providers, WebView and local web servers, with PoCs and fixes.
Document

What it is

Oversecured's checklist of seven ways an attacker can read files from an Android app's private storage (/data/user/0/{package_name}). Each has vulnerable code and an attacker PoC. The page treats anything under /storage/emulated/0 as public, and notes that apps sharing an android:sharedUserId can read each other's files, so one app can be used to attack another.

How it works

Most attacks make the victim copy a private file somewhere readable, such as getExternalCacheDir(), or send it onward, for example to a chat.

  • Implicit intents (PICK, GET_CONTENT, IMAGE_CAPTURE, CROP and others): a malicious app registers a matching intent filter and returns a file:///data/user/0/com.victim/shared_prefs/secrets.xml URI. The victim's onActivityResult passes it to openInputStream and copies the contents out.
  • SEND / SEND_MULTIPLE activities: the attacker starts the exported share activity directly, with the same file:// URI in EXTRA_STREAM.
  • file:// guard: FileUriExposedException applies by default, but the attacker bypasses it in their own process with StrictMode.setVmPolicy(StrictMode.VmPolicy.LAX).
  • Non-exported FileProviders: these are still exploitable. Android checks permissions only when the caller accesses data, and here the victim itself is the one opening its own resource. Oversecured reports findings in Google and TikTok apps, and says more than 90% of the apps it analyzes have provider-related errors of varying severity.
  • Exported providers: a provider that builds new File(root, uri.getPath()) allows traversal with content://com.victim.myprovider/../../shared_prefs/secrets.xml. The page cites a pre-installed Samsung app where the provider was exported behind only a weak permission.
  • Path decoding: Uri.getLastPathSegment() and similar calls decode %2F to /, which reopens traversal.
  • grantUriPermissions="true" providers: if an attacker can steer the victim's intents (custom Data, ClipData, or the FLAG_GRANT_*_URI_PERMISSION flags), they can reach any of the app's providers. The page defers the details to a separate article.
  • Local NanoHTTPD servers: a server on port 8080 that does new File(context.getCacheDir(), path) from the request URI is path-traversable. It is also reachable from the local network while the app runs.
  • WebView: the page only links out to other articles (insecure WebResourceResponse, XHR with file access from file URLs, file choosers).

What to do

  • Do not use public storage for caching or other operations.
  • Before using an external file:// or content:// URI, check where it really points. The page's check opens a file descriptor and compares its resolved path with the app's data directory:
private static boolean isInternalUri(Context context, Uri uri) throws IOException {
    ParcelFileDescriptor fd = context.getContentResolver().openFileDescriptor(uri, "r");
    return isInternalFile(context, fd);
}
private static boolean isInternalFile(Context context, ParcelFileDescriptor fileDescriptor) throws IOException {
    int fd = fileDescriptor.getFd();
    Path fdPath = Paths.get("/proc/self/fd/" + fd);
    Path filePath = Files.readSymbolicLink(fdPath);
    Path internalPath = Paths.get(context.getApplicationInfo().dataDir);
    return filePath.startsWith(internalPath);
}
  • Narrow FileProvider paths. <files-path name="files" path="." /> is unsafe; use <files-path name="files" path="my_saved_files" />. Audit every provider for root-path, files-path or cache-path entries and for path traversal.
  • Do not export a provider meant only for in-app sharing. For cross-app sharing, require a signature permission. Alternatively, keep it non-exported with android:grantUriPermissions="true" so the app grants access to specific URIs only.
  • For local web servers, first ask whether one is needed. If so, validate paths against traversal, treat the code like any web app, and serve from a dedicated folder such as cache/web_cache rather than the whole cache directory.

Caveats

The page is also a pitch for Oversecured's scanner, and the 90% figure is the vendor's internal statistic. The exported-provider example builds its path from uri.getPath(), while the prose blames getLastPathSegment(). The WebView and grantUriPermissions cases are only summarized, with details left to other articles.

Organisations named here

  • FileUriExposedException
  • grantUriPermissions
  • Oversecured Vulnerable Android App

Technologies named here

  • Oversecured
  • Android apps
  • Android
  • Java
  • Amazon apps (WebResourceResponse file theft example, described in a separate article)
  • Android apps running local web servers with NanoHTTPD
  • Android apps with targetSdkVersion 18 or higher (FileUriExposedException on file:// URIs)
  • Android content providers (exported, or with android:grantUriPermissions="true")
  • Android FileProvider (root-path, files-path, cache-path configurations)
  • Android SDK 29 and up (restrictions on access to certain directories)
  • Android WebView
  • Apps sharing the same android:sharedUserId
  • FileProvider
  • Google apps (provider vulnerabilities found by Oversecured)
  • NanoHTTPD
  • Oversecured Vulnerable Android App (OVAA)
  • Pre-installed Samsung system app (exported provider protected only by a weak permission)
  • StrictMode
  • TikTok app (provider vulnerabilities found by Oversecured)
  • WebView

Techniques named here

  • Path traversal
  • Arbitrary content provider access via grantUriPermissions
  • file:// URI attack
  • Implicit intent interception
  • Malicious sharing intent (SEND / SEND_MULTIPLE with EXTRA_STREAM)
  • Path traversal in exported content provider
  • Path traversal in local web server
  • Shared user ID exploitation
  • Theft of arbitrary files from app private storage
  • WebView file theft

Also named here

  • CWE-22