Перейти к содержанию

Обнаружены «внутренние домены», заданные для поиска

Описание

Во время статического анализа декомпилированных исходников инструментарий обнаружил строки-URL, соответствующие паттернам «внутренних доменов», указанных пользователем. Факт присутствия таких доменов в финальной сборке свидетельствует о том, что разработчики забыли удалить или заменить служебные или тестовые адреса (например, https://staging.company.internal/api), используемые на этапе разработки или внутренних тестов.

Наличие внутренних доменов в опубликованном APK может привести к ряду негативных последствий:

  • Раскрытие внутренней инфраструктуры: злоумышленник получает информацию о структуре сети, названиях сервисов, используемых технологиях (например, kibana.dev.company.local).
  • Внешний доступ к незащищённым средам: если тестовый или staging-сервер доступны извне, их можно атаковать для обхода основного контура безопасности.
  • Утечка логики и данных: сборка может обращаться к эндпоинтам без полноценной аутентификации, раскрывая внутренние API-методы или тестовые данные.
  • Возможность подмены ответов (MITM): внутренние адреса часто обслуживаются без TLS-сертификатов, валидных в публичном Интернете. Злоумышленник может эмулировать эти домены и вернуть произвольный ответ.

Типовые сценарии обнаружения:

  1. Жёстко прописанные строки-URL в коде (.java, .kt) или ресурсах (strings.xml).
  2. Файлы конфигурации (JSON, YAML, Protobuf) внутри APK, где сохранены тестовые эндпоинты.
  3. Логику переключения окружений без отключения «dev»/«staging» веток в релиз-сборке:
const val BASE_URL = if (BuildConfig.DEBUG) {
    "https://api.staging.company.internal"
} else {
    "https://api.prod.company.com"
}
// При ошибочном флаге или переопределении через buildVariant внутренняя ссылка окажется в релизе

Рекомендации

  1. Сконфигурировать сборочный процесс:

    • Храните адреса окружений в gradle-профилях или CI/CD-секретах, а не в коде.
    • Убедитесь, что продакшн-домены подставляются только для релизных buildTypes и productFlavors.
    // build.gradle (Module)
    buildTypes {
        debug {
            buildConfigField "String", "BASE_URL", "\"https://api.staging.company.internal\""
        }
        release {
            buildConfigField "String", "BASE_URL", "\"https://api.prod.company.com\""
            // Запретить отладочную информацию
            debuggable false
            minifyEnabled true
        }
    }
    
  2. Использовать централизованное хранилище конфигурации:

    • Для смены окружений применяйте Remote Config, Firebase, ConfigCat или аналогичные сервисы с возможностью feature flags.
    • Это позволит изменять цели API без пересборки приложения и без риска утечки внутренних адресов.
  3. Шифровать чувствительные строки:

    • Если по техническим причинам необходимо оставить внутренний домен в приложении (например, для fallback), храните его в зашифрованном виде и расшифровывайте только в рантайме через Android Keystore.
    • Учтите, что это не основной способ защиты, а лишь затрудняет тривиальное извлечение строки.

Ссылки

  1. OWASP Mobile Security Testing Guide — «Code Quality & Build Settings»
  2. Android Developers — «Configure build variants»
  3. Google Play Console — «Use Play App Signing»
  4. Medium — «Mobile Application Penetration Testing Checklist: Sensitive Data Exposure»
К началу