The code below sets up a FileProvider to share lab report PDFs with external apps (e.g., email clients or document viewers). While the provider is not directly exported (android:exported="false"), it enables URI grants via android:grantUriPermissions="true". The filepaths.xml resource uses path=".", which exposes the entire internal filesDir, including sensitive files such as session_token.txt, to any app that receives a URI grant.
The Android Manifest exports the activity ShareReportActivity that can be queried by any other app.
packageorg.owasp.mastestappimportandroid.app.Activityimportandroid.content.Contextimportandroid.content.Intentimportandroid.os.Bundleimportandroidx.core.content.FileProviderimportjava.io.File// SUMMARY: Demonstrates oversharing via FileProvider misconfiguration where filepaths.xml uses path="." exposing the entire internal files directory.// FAIL: [MASTG-TEST-0357] FileProvider is configured with path="." in filepaths.xml, which exposes all files in filesDir — not just the intended reports subdirectory.classMastgTest(privatevalcontext:Context){funmastgTest():String{valr=DemoResults("0122")returntry{File(context.filesDir,"session_token.txt").writeText("sess_7f3a9b1e4d2c8f0a5e6b3c1d9f4a2e7b")File(context.filesDir,"reports").mkdirs()File(context.filesDir,"reports/lab_result_3829.pdf").writeText("%PDF-1.4 stub: cholesterol 195, HbA1c 6.8")r.add(Status.FAIL,"FileProvider path=\".\" exposes all of filesDir. "+"Intended: content://org.owasp.mastestapp.fileprovider/app_files/reports/lab_result_3829.pdf — "+"but session_token.txt is also reachable via the same authority.")r.toJson()}catch(e:Exception){r.add(Status.ERROR,"${e.javaClass.simpleName}: ${e.message}")r.toJson()}}// INTENTIONALLY VULNERABLE: exported activity that wraps attacker-controlled// filenames into FileProvider URIs and grants read access back to the caller.classShareReportActivity:Activity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)valrequested=intent.getStringExtra("file_name")?:run{setResult(RESULT_CANCELED);finish();return}valfile=File(filesDir,requested)valuri=FileProvider.getUriForFile(this,"org.owasp.mastestapp.fileprovider",file)valresult=Intent().apply{data=uriaddFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)}setResult(RESULT_OK,result)finish()}}}
The rule flags the files-path element with path=".".
output.txt
1 2 3 4 5 6 7 8 9101112131415
┌────────────────┐│1CodeFinding│└────────────────┘filepaths_reversed.xml❯❱rules.mastg-android-fileprovider-broad-path-scope[MASVS-PLATFORM]FileProviderpathelementisdeclaredwithpath=".",whichmapstheentirecorrespondingbasedirectoryintotheprovider's addressable namespace. Any file under that directorybecomesreachablethroughFileProvider.getUriForFile(),includingsecretsorfilesaddedlater.Narrowthepathtoaspecificsubdirectorycontainingonlyfilesintendedforsharing(e.g.path="reports/").3┆<files-path4┆name="app_files"5┆path="."/>
The test case fails because the FileProvider path configuration exposes the entire filesDir instead of only the intended reports/ subdirectory.
The rule flags the files-path element in filepaths.xml:
path="." is an overly broad scope that grants URI-grant access to every file under filesDir, not just the intended reports/ subdirectory. Any app that receives a URI grant from the victim's ShareReportActivity can request any filename — including sensitive files such as session_token.txt.
Additionally, ShareReportActivity is declared with android:exported="true" in the AndroidManifest, meaning any external app can send it a crafted intent with an arbitrary file_name extra and receive back a valid content:// URI.
This attack cannot be reproduced with adb alone. adb shell am start can launch the exported activity, but it never receives the returned result intent or the temporary URI permission grant, so it can't read the file — and reading it via su -c 'content read …' only works because root can read any app's storage directly, which bypasses the provider rather than exploiting it. Demonstrating the real vulnerability therefore requires a separate attacker app that calls the activity with startActivityForResult() and reads the granted content:// URI.