File verification
Verify files​
Imagine you have written code that looks like this:
if (intent.action == Intent.ACTION_SEND) {
val uri = intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as Uri
sendData(contentResolver.openInputStream(uri))
}
Your application in this case might be at risk of an attack that looks like this:
Intent(Intent.ACTION_SEND).apply {
putExtra(
Intent.EXTRA_STREAM,
Uri.parse("file:///data/data/${it.packageName}/db/sensitive.db")
)
}
In this example, we might allow an attacker to send sensitive keys, databases (etc).
Allow no private apps​
To prevent this type of attack, we can use the verify command in order to check a file (or a URI) before opening it.
val isFileSafeToOpen = uri.verifyFile(this) {}
By default, no files from your private directory is allowed - which is what you want in most cases.
Allow specific private file​
We can allow a specific file
val isFileSafeToOpen = uri.verifyFile(this) {
// This
File(context.filesDir + "files/", "safe_to_read.txt").allowExactFile()
// Is the same as this:
addAllowedExactFile(File(context.filesDir + "files/", "safe_to_read.txt"))
}
Allow all files in a directory​
Instead of this, we can add a directory and allow all files in that directory
val isFileSafeToOpen = uri.verifyFile(this) {
// This
addAllowedParentDirectory(context.filesDir.allowDirectory())
// Is the same as this:
FileUriMatcherBuilder.FileUriMatcherCheck(
context.filesDir,
false
)
}
Allow all files and subdirectories​
At the moment /data/data/com.safe.to.run/files/abc.txt
would be allowed,
but /data/data/com.safe.to.run/files/subdir/abc.txt
would not. To allow subdirectories:
val isFileSafeToOpen = uri.verifyFile(this) {
// This
addAllowedParentDirectory(context.filesDir.allowDirectoryAndSubdirectories())
// Is the same as this:
FileUriMatcherBuilder.FileUriMatcherCheck(
context.filesDir,
true
)
}
Allow any file​
We would not recommend doing this:
val isFileSafeToOpen = uri.verifyFile(this) {
allowAnyFile = true
}