File verification
File verification ensures that files go where they should go - stop directory traversal attacks early with default deny, and explicit allow on every file
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/com.my.app/db/sensitive.db")
)
}
In this example, we might allow an attacker to send sensitive keys, databases (etc).
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.
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"))
}
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 )
}
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)
}
We would not recommend doing this :
⛔
val isFileSafeToOpen = uri.verifyFile(this) {
allowAnyFile = true
}
Last modified 6mo ago