Возможность получения доступа к произвольному файлу
![]() |
Критичность: СРЕДНИЙ |
| Способ обнаружения: IAST |
Описание
Уязвимость позволяет получить доступ к произвольным файлам приложения.
Уязвимость присутствует в приложениях, которые не проводят надлежащим образом проверку входного Uri-параметра и используют его для обращения к методам работы с файлами. Вредоносное приложение может специальным образом сформировать Uri, передать его тем или иным способом в уязвимое приложение и получить доступ к произвольному файлу.
Пример уязвимого кода:
private void takeSomeSharedFile() {
Intent interceptableIntent = new Intent("vuln.app.pkg.INTERCAPTABLE");
startActivityForResult(interceptableIntent, 1001);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == -1 && data != null) {
if(requestCode == 1001) {
copyToCache(data.getData());
}
}
}
public static File copyToCache(Uri uri) {
try {
File out = new File(getExternalCacheDir(), "" + System.currentTimeMillis());
InputStream i = getContentResolver().openInputStream(uri);
OutputStream o = new FileOutputStream(out);
IOUtils.copy(i, o);
i.close();
o.close();
return out;
}
catch (Exception e) {
return null;
}
}
Вредоносное приложение может использовать такой код:
Intent intent = new Intent();
File privFile = new File("/data/data/vuln.app.pkg/databases/main.db");
intent.setData(Uri.fromFile(privFile));
setResult(RESULT_OK, intent);
finish();
В результате уязвимое приложение скопирует файл main.db в файл /storage/emulated/0/Android/data/vuln.app.pkg/1650464271, доступ к которому может получить вредоносное приложение.
Проблема
Если приложение использует пришедший извне Uri (или путь) для файловых операций без проверки, вредоносное приложение может с помощью символов обхода каталога (../) или прямого указания пути выйти за пределы разрешённого каталога. Это приводит к чтению или перезаписи произвольных файлов в приватной директории приложения, утечке конфиденциальных данных и, в зависимости от операции, к компрометации приложения.
Рекомендации
Необходимо проводить валидацию canonical-пути файла непосредственно перед вызовом методов файловых операций над этим файлом.
Важно сравнивать префикс с канонизированным базовым каталогом, к которому добавлен завершающий разделитель (File.separator). Проверка вида canonicalPath.startsWith(sdcardDir) без разделителя обходится: например, для sdcardDir = "/data/files" путь /data/files_evil пройдёт проверку, хотя находится вне целевого каталога.
String canonicalDir = new File(sdcardDir).getCanonicalPath();
File file = new File(canonicalDir, uri.getLastPathSegment());
String canonicalPath = file.getCanonicalPath();
if (!canonicalPath.equals(canonicalDir)
&& !canonicalPath.startsWith(canonicalDir + File.separator)) {
throw new IllegalArgumentException();
}
Дополнительно:
- по возможности не принимайте от сторонних приложений произвольный
Uri/путь, а используйте безопасные механизмы обмена файлами (FileProviderс заранее заданными путями); - проверяйте, что итоговый файл действительно является ожидаемой целью (например, лежит в выделенном подкаталоге);
- не выполняйте файловые операции с повышенными привилегиями над путями, полученными извне.
