Категория OWASP: MASVS-CODE: Качество кода
Обзор
Небезопасная загрузка URI происходит, когда приложение Android не может правильно оценить допустимость URI перед загрузкой его в WebView.
Основная причина этого типа уязвимости заключается в том, что URI состоит из нескольких частей , из которых, как минимум, схема и хост (авторитетной части) должны быть проверены (например, внесены в список разрешенных), прежде чем URI будет загружен в WebView. или используется внутри приложения.
К наиболее частым ошибкам относятся:
- Проверка хоста, но не схемы, что позволяет злоумышленнику использовать такие схемы, как
http://
,content://
илиjavascript://
с аутентифицированным хостом. - Не удалось правильно проанализировать URI, особенно в тех случаях, когда URI получен в виде строки.
- Проверка схемы, но не хоста (недостаточная проверка хоста).
Что касается последнего случая, то это обычно происходит, когда приложению необходимо разрешить произвольные поддомены основного домена. Таким образом, даже если имя хоста было извлечено правильно, приложение использует такие методы, как startsWith
, endsWith,
или contains
класс java.lang.String
, чтобы проверить наличие основного домена в извлеченном разделе строки. При неправильном использовании эти методы могут привести к ошибочным результатам и заставить приложение неправильно доверять потенциально вредоносному хосту.
Влияние
В зависимости от контекста, в котором используется хост, влияние может различаться. В случаях, когда загрузка вредоносного URI (т. е. того, который обходит фильтрацию/белый список) в WebView потенциально может привести к захвату учетной записи (например, с помощью фишинга), выполнению кода (например, загрузке вредоносного JavaScript) или компрометации устройства (код эксплойта, доставленный с помощью гиперссылка).
Смягчения
При обработке строковых URI важно проанализировать строку как URI и проверить как схему, так и хост:
Котлин
fun isUriTrusted(incomingUri: String, trustedHostName: String): Boolean {
try {
val uri = Uri.parse(incomingUri)
return uri.scheme == "https" && uri.host == trustedHostName
} catch (e: NullPointerException) {
throw NullPointerException("incomingUri is null or not well-formed")
}
}
Ява
public static boolean isUriTrusted(String incomingUri, String trustedHostName)
throws NullPointerException {
try {
Uri uri = Uri.parse(incomingUri);
return uri.getScheme().equals("https") &&
uri.getHost().equals(trustedHostName);
} catch (NullPointerException e) {
throw new NullPointerException(
"incomingUri is null or not well-formed");
}
}
Для проверки хоста после изоляции соответствующей части URI важно проверить ее полностью (а не частично), чтобы точно определить, является ли хост надежным или нет. Если нельзя избежать использования таких методов, как startsWith
или endsWith
, важно использовать правильный синтаксис и не упускать из виду необходимые символы или символы (например, для endsWith
требуется точка « .
» перед именем домена для точного соответствия). Игнорирование этих символов может привести к неточным совпадениям и поставить под угрозу безопасность. Поскольку субдомены могут быть бесконечно вложенными, сопоставление регулярных выражений не является рекомендуемой стратегией проверки имен хостов.
Авторы: Димитриос Вальсамарас и Майкл Пек из Microsoft Threat Intelligence