Защитите конфиденциальность ваших пользователей: безопасность приложений Android для разработчиков
Если вы собираетесь сохранить свою аудиторию и свою репутацию надежного разработчика Android, вам как разработчику необходимо серьезно отнестись к безопасности приложений Android.
Если в вашем приложении когда-либо произойдет утечка личных данных, вы рискуете потерять большую часть своей аудитории. Сегодняшние технически подкованные мобильные пользователи понимают, что лучший способ защитить себя от небезопасного приложения – это удалить его со своего устройства. СМИ также все чаще сообщают о серьезных утечках данных, поэтому небрежный подход к мобильной безопасности может привести к очень плохой огласке.
Ставки высоки, и с постоянным выпуском новых вредоносных приложений все возрастает вероятность того, что ваше приложение может совместно использовать устройство с вредоносным ПО и вредоносным сторонним кодом.
Небрежный подход к мобильной безопасности может привести к очень плохой рекламе.
К счастью, Android имеет широкий спектр встроенных функций безопасности, которые могут помочь надежно заблокировать данные ваших пользователей. В этой статье мы рассмотрим все основные функции конфиденциальности, встроенные в платформу Android, а также дополнительные инструменты, методы и передовые методы, которые вы можете использовать, чтобы гарантировать конфиденциальность данных вашего частного приложения.
Держите свои зависимости в актуальном состоянии
Современные мобильные приложения нередко используют несколько библиотек, SDK и многие другие зависимости. Новые выпуски этих зависимостей часто содержат исправления ошибок, патчи и другие функции безопасности, поэтому вам необходимо убедиться, что вы используете самые последние версии при разработке своего приложения.
Перед развертыванием приложения также рекомендуется выполнить последнюю проверку, чтобы убедиться, что обновления отсутствуют.
Если ваше приложение использует сервисы Google Play, вы можете проверить, установлена ли на устройстве пользователя самая последняя версия, а затем при необходимости запустить обновление.
Чтобы проверить, обновлены ли сервисы Google Play на устройстве, вызовите метод installIfNeeded() класса ProviderInstaller. Если доступно обновление, этот метод вызовет исключение авторизации, и пользователю будет предложено обновить службы Google Play на своем устройстве.
Ограничьте количество запросов на разрешение
Если у вашего приложения нет доступа к разрешению, вероятность того, что оно неправильно обработает какие-либо конфиденциальные данные или функции, связанные с этим разрешением, отсутствует. Ограничение доступа к конфиденциальным разрешениям также может сделать ваше приложение менее привлекательной целью для хакеров, поэтому важно запрашивать как можно меньше разрешений.
Прежде чем делать какие-либо запросы на разрешение, вы должны подумать, есть ли способ достичь того же результата, не имея доступа к этому разрешению. Например, если вам нужно сохранить некоторые данные, вы можете получить доступ к локальному хранилищу без запроса каких-либо разрешений, а не пытаться сохранить данные извне, для чего требуется разрешение WRITE_EXTERNAL_STORAGE.
В качестве альтернативы вы можете использовать намерения для передачи задачи приложению, у которого уже есть необходимые разрешения. Например, вместо запроса разрешений READ_CONTACTS и WRITE_CONTACTS вы можете делегировать задачу приложению Контакты:
Intent contactIntent =
Вам также следует отказаться от любых разрешений, которые больше не требуются вашему приложению, что может значительно сократить объем конфиденциальных данных и функций, к которым ваше приложение имеет доступ в любой момент.
Позвольте пользователям решать: отображение средства выбора приложения
Зачем тратить время и силы на изобретение колеса? Неявные намерения позволяют выполнять задачи в сотрудничестве со сторонними приложениями, уменьшая объем кода, который необходимо написать, чтобы предоставить все необходимые функции вашего приложения. Передав задачу другому приложению, вы также можете уменьшить количество разрешений, необходимых вашему приложению.
Неявные намерения могут сэкономить вам массу времени, но они также дают вам нулевой контроль над тем, какое приложение отвечает на ваш запрос. Если небезопасное или вредоносное стороннее приложение отвечает на ваше неявное намерение, есть вероятность, что вы можете непреднамеренно раскрыть личные данные пользователя третьему лицу. Если конфиденциальность пользователя нарушена в результате действия стороннего приложения, ваше приложение может быть признано виновным по ассоциации.
При выдаче неявного намерения вы должны отображать средство выбора приложения Android везде, где это возможно.
Предоставляя пользователю список всех приложений, которые могут реагировать на это намерение, вы даете ему возможность выбрать приложение, которому он лично доверяет. Хотя нет никаких гарантий, что каждый пользователь сделает правильный выбор, это может снизить вероятность того, что вы поделитесь данными с ненадежным приложением.
При выдаче намерения вы должны проверить, есть ли у пользователя несколько приложений, которые могут обрабатывать это намерение. Предполагая, что доступно несколько совместимых приложений, вы можете отобразить средство выбора приложения, вызвав createChooser () и передав его в startActivity ():
Intent myIntent =
Обратите внимание, что вы никогда не должны использовать неявное намерение для запуска Службы, так как вы не сможете контролировать, какая Служба отвечает на ваше неявное намерение.
Избегайте внешнего хранилища
Вам необходимо убедиться, что любые данные, которые вы храните на устройстве пользователя, недоступны для других приложений, если вы не дадите этим приложениям явное разрешение.
Файлы, сохраненные во внешнем хранилище, доступны для чтения и записи глобально, поэтому любые данные, которые вы сохраняете во внешнем хранилище, потенциально могут быть доступны и изменены любым другим приложением. Также нет гарантии, что внешний носитель данных останется подключенным к текущему смартфону или планшету. Если ваше приложение записывает во внешнее хранилище, вы потенциально можете сохранять конфиденциальные пользовательские данные на SD-карту, которая позже будет удалена и вставлена на чужое устройство!
Если у вас нет особой причины не делать этого, вы всегда должны сохранять данные во внутреннем хранилище, где они изолированы и будут доступны только вашему приложению по умолчанию. Кроме того, если пользователь удалит ваше приложение, все файлы вашего приложения будут автоматически удалены из внутреннего хранилища, поэтому вам не нужно беспокоиться о том, чтобы оставить какую-либо конфиденциальную информацию.
В следующем фрагменте мы записываем данные во внутреннее хранилище:
final
Если данные особенно конфиденциальны, вы можете обеспечить дополнительную безопасность приложения Android, зашифровав файлы с помощью ключа, недоступного для вашего приложения, например ключа, который помещается в хранилище ключей и защищен паролем, который не хранится в нем. Устройство.
Используйте новый доступ к каталогам Android
Иногда приложению может потребоваться доступ к определенным каталогам во внешнем хранилище устройства, например, получение доступа к внешнему каталогу изображений устройства.
Хотя вы можете запросить разрешение READ_EXTERNAL_STORAGE, это часто предоставит вашему приложению доступ к большему количеству данных, чем ему нужно. Приложение не может неправильно обрабатывать данные, к которым у него нет доступа, поэтому вам следует попытаться минимизировать объем информации, к которой ваше приложение может получить доступ, где это возможно.
Вместо запроса разрешения READ_EXTERNAL_STORAGE вы можете запросить доступ к определенному каталогу. Для доступа к каталогу с заданной областью необходимо использовать класс StorageManager, а затем создать намерение, вызвав метод StorageVolume.createAccessIntent () этого экземпляра. Например, в следующем фрагменте мы обращаемся к внешнему каталогу Pictures:
StorageManager newStorageManager = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
StorageVolume volume = newStorageManager.getPrimaryStorageVolume();
Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code);
Если пользователь действительно предоставляет вашему приложению доступ к этому внешнему каталогу, тогда Android вызовет ваше переопределение onActivityResult () с кодом результата RESULT_OK, а также намерением, содержащим URI для запрошенного каталога.
Никогда не кешируйте конфиденциальные пользовательские данные
При обработке неконфиденциальных данных приложения вы можете улучшить взаимодействие с пользователем, сохранив эти данные в кэше устройства.
Для кешей размером более 1 МБ вы можете использовать getExternalCacheDir (), который вернет путь к каталогу для конкретного приложения, где вы можете хранить кэшированный контент.
Если вы все же решите кэшировать, просто имейте в виду, что любое приложение с разрешением WRITE_EXTERNAL_STORAGE потенциально может записывать в эти файлы, поэтому вам никогда не следует хранить личную или конфиденциальную информацию в кеше, если вы заботитесь о безопасности приложений Android.
Защитите свои ключи от несанкционированного использования
Система Android Keystore позволяет хранить криптографические ключи в контейнере, что затрудняет извлечение этих ключей с устройства.
Android Keystore гарантирует, что ключевой материал никогда не попадет в процесс приложения, поэтому даже если процессы вашего приложения будут скомпрометированы и злоумышленник сможет получить доступ к вашим ключам, он не сможет извлечь свой ключевой материал.
Вы также можете использовать Keystore, чтобы ограничить, когда и как могут использоваться ваши ключи, например, вы можете ограничить использование ключей определенными криптографическими режимами или потребовать аутентификации пользователя.
Сделайте своих ContentProviders приватными
ContentProviders – это структурированный механизм хранения, который вы можете сделать частным для своего приложения или выбрать экспорт, после чего они станут доступными для других приложений.
Если вам явно не нужно обмениваться данными со сторонним приложением, вы должны сделать все свои ContentProviders закрытыми, пометив их как android: exported = false в манифесте вашего приложения. Если ваше приложение совместимо с Android 4.1.1 или ниже, то особенно важно, чтобы вы пометили свои частные ContentProvider как android: exported = false, поскольку все ContentProvider по умолчанию являются общедоступными.
<provider
Отпечатки пальцев ваших пользователей с биометрической аутентификацией
Прежде чем разрешить пользователю доступ к любой конфиденциальной информации или функциям вашего приложения, вы должны подтвердить его личность, запросив его учетные данные.
Учетные данные пользователя могут принимать форму ПИН-кода или пароля, однако там, где это возможно, гораздо безопаснее выполнять биометрическую аутентификацию, например, запрашивая отпечаток пальца пользователя.
Соблюдайте все передовые методы работы в сети
В отличие от менее портативных устройств, таких как настольные компьютеры, мы часто подключаем наши смартфоны и планшеты к незащищенным беспроводным сетям, таким как бесплатный общедоступный Wi-Fi. Чтобы сохранить конфиденциальность пользователя, вы должны относиться ко всем сетевым транзакциям как к рискованным по своей природе, особенно при передаче пользовательских данных.
Всякий раз, когда вам нужно выполнить сетевую транзакцию, важно следовать всем рекомендациям по работе с сетью Android:
- Используйте HTTPS вместо HTTP, если он поддерживается на сервере.
- Никогда не доверяйте данным, загруженным из небезопасных протоколов, включая любые ответы, отправленные по протоколу HTTP.
- Используйте соответствующие протоколы для конфиденциальных данных, такие как HttpsURLConnection.
- Там, где возможна аутентификация, используйте механизм Android IPC, например Сервис.
- Используйте инструмент сетевой безопасности Nogotofail с открытым исходным кодом, чтобы протестировать свое приложение на наличие известных уязвимостей и ошибок конфигурации TLS / SSL. Nogotofail включает тесты для выявления распространенных проблем проверки сертификатов SSL, ошибок библиотек HTTPS и TLS / SSL, проблем с открытым текстом и проблем с удалением SSL и STARTTLS. Для получения дополнительной информации посетите страницу Nogotofail на GitHub.
- По возможности избегайте загрузки кода из-за пределов APK, поскольку это увеличивает вероятность того, что кто-то в сети изменит ваш код во время передачи.
Используйте WebViews с осторожностью
Компонент WebView может использовать HTML и JavaScript, поэтому при неправильном использовании WebView ваше приложение будет уязвимо для распространенных проблем веб-безопасности, таких как межсайтовый скриптинг.
Если вы неправильно используете WebViews, ваше приложение будет уязвимо для распространенных проблем веб-безопасности.
Чтобы обеспечить безопасность пользователей Android, компонент WebView по умолчанию не выполняет JavaScript. Однако при необходимости вы можете включить JavaScript, используя getSettings () для получения WebSettings, а затем запустив метод setJavaScriptEnabled ():
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(
Даже если вам действительно нужно включить JavaScript, вам следует по возможности избегать использования addJavaScriptInterface (), поскольку этот метод внедряет предоставленный объект Java в компонент WebView. Если ваше приложение установлено на устройстве под управлением Android 4.2 или более ранней версии, этот метод потенциально может позволить JavaScript манипулировать вашим приложением.
Если вы используете WebViews, вы не должны позволять пользователям переходить на какой-либо веб-сайт, который вы не контролируете, но, в частности, вы никогда не должны использовать метод addJavascriptInterface (), если пользователь потенциально может перейти на ненадежную веб-страницу, так как это представляет собой огромную угрозу безопасности приложений Android.
Никогда не следует использовать метод addJavascriptInterface (), если пользователь потенциально может перейти на ненадежную веб-страницу.
Если ваш компонент WebView обращается к каким-либо личным данным, вы можете периодически удалять любые файлы, которые хранятся локально, с помощью метода clearCache (). Кроме того, вы можете запретить вашему приложению кэшировать конфиденциальный контент, используя серверный заголовок без кеширования.
Управление протоколом защищенных сокетов (SSL) вашего приложения
SSL – распространенный компонент зашифрованной связи между клиентами и серверами. Если ваше приложение неправильно использует SSL, третьи злоумышленники могут потенциально перехватить данные вашего приложения во время их передачи по сети.
Обычно сервер настраивается с сертификатом, содержащим открытый ключ и соответствующий закрытый ключ. В рамках обмена данными между клиентом SSL и сервером сервер подписывает свой сертификат с помощью криптографии с открытым ключом. Тем не менее, третья сторона может сгенерировать свой собственный сертификат и закрытый ключ, поэтому у вашего клиента также должен быть один или несколько сертификатов, которым он доверяет. Если сертификат не установлен, ваше приложение не должно доверять серверу.
Чтобы упростить этот процесс, серверы часто настраиваются с использованием сертификатов известных центров сертификации (ЦС). Начиная с уровня API 17, Android поддерживает более 100 центров сертификации, которые обновляются с каждым выпуском. При выдаче сертификата для сервера ЦС подписывает сертификат сервера, используя свой закрытый ключ, а затем клиент может проверить, что сертификат выпущен ЦС, который известен и которому доверяет платформа Android.
Если ваше приложение обменивается данными с веб-сервером, у которого есть сертификат, выданный доверенным центром сертификации, вы можете сделать свой запрос в нескольких строках кода:
URL url =
Однако есть несколько сценариев, в которых приведенный выше код приведет к исключению:
- ЦС, выдавший сертификат сервера, неизвестен. В этом сценарии вы можете научить HttpsURLConnection доверять этому набору центров сертификации.
- Сертификат сервера был самоподписанным, что означает, что сервер действует как собственный центр сертификации. Для самозаверяющих сертификатов вы можете создать свой собственный TrustManager, хотя вы должны убедиться, что ваш самозаверяющий сертификат имеет надежный ключ.
- В конфигурации сервера отсутствует промежуточный ЦС. Многие общедоступные центры сертификации не подписывают сертификаты сервера напрямую. Android доверяет только корневым ЦС, поэтому серверу необходимо будет отправить цепочку сертификатов из ЦС сервера через любые промежуточные звенья, необходимые для доступа к корневому ЦС. Если вы не можете настроить сервер для включения промежуточного ЦС в цепочку серверов, то одним из возможных обходных путей является создание собственного TrustManager.
Создание файла конфигурации сетевой безопасности: доверие настраиваемым центрам сертификации
Если вы хотите, чтобы ваше приложение использовало новый или настраиваемый ЦС, вам следует создать файл конфигурации сетевой безопасности, в котором вы укажете свои параметры сетевой безопасности.
Чтобы создать файл конфигурации сетевой безопасности:
- Если в вашем проекте еще нет папки XML, вам необходимо ее создать. Удерживая нажатой клавишу Control, щелкните папку res вашего проекта и выберите «Создать»> «Каталог ресурсов Android».
- Создайте новый файл ресурсов XML в каталоге XML, который будет служить файлом конфигурации сетевой безопасности. Я называю этот файл network_config.
- Откройте файл конфигурации сети и укажите, что весь трафик в следующие домены должен использовать HTTPS:
<?xml version="1.0" encoding="utf-8"?>
Теперь вы можете указать набор настраиваемых центров сертификации, которым ваше приложение должно доверять. Например, если вы хотите подключиться к хосту, который использует самозаверяющий ЦС, вы должны добавить следующее в файл конфигурации сетевой безопасности:
<?xml version="1.0" encoding="utf-8"?>
Не забудьте объявить файл конфигурации сетевой безопасности в своем манифесте:
<?xml version="1.0" encoding="utf-8"?>
Наконец, вам нужно добавить самозаверяющий сертификат CA в каталог res / raw / custom_ca вашего проекта в формате PEM или DER, и ваше приложение сможет подключиться к хосту.
Ограничьте список доверенных центров сертификации
В качестве альтернативы вы можете захотеть повысить безопасность своей сети, подключаясь только к центрам сертификации, которые вы знаете и которым доверяете, вместо того, чтобы автоматически доверять каждому центру сертификации, известному платформе Android.
Чтобы ограничить ваше приложение меньшим набором центров сертификации, добавьте следующее в файл конфигурации сетевой безопасности:
Затем вам нужно будет добавить доверенные центры сертификации в файл res / raw / trust_cas вашего проекта в формате PEM или DER.
При необходимости доверяйте дополнительным центрам сертификации
Наконец, вы можете доверять дополнительным центрам сертификации, которые не известны платформе Android. Чтобы увеличить количество центров сертификации, которым доверяет ваше приложение, вам необходимо указать несколько источников сертификатов:
Никогда не отправляйте конфиденциальные данные по SMS
Если вам нужно передать данные с сервера в ваше приложение, вам следует использовать Google Cloud Messaging (GCM) и IP-сообщения, а не незашифрованный протокол SMS.
Читайте также: Разработка Android: как звонить, получать SMS и получать контакты пользователей
Вы также никогда не должны выполнять конфиденциальные команды с помощью SMS-сообщений, поскольку SMS-сообщения передаются как широковещательные, что означает, что любое приложение с разрешением READ_SMS сможет получить доступ к их содержимому.
Защита от угроз безопасности с помощью API-интерфейсов SafetyNet
SafetyNet предоставляет набор служб и API-интерфейсов, которые вы можете использовать для защиты вашего приложения от угроз безопасности, таких как взлом устройства, вредоносные URL-адреса и поддельные пользователи.
Android поддерживает следующие API-интерфейсы SafetyNet:
- API аттестации SafetyNet. Этот API для защиты от злоупотреблений позволяет вам получить доступ к устройству Android, на котором работает ваше приложение, чтобы вы могли определить, взаимодействуют ли ваши серверы с подлинным устройством.
- API безопасного просмотра SafetyNet. Вы можете использовать этот API, чтобы определить, классифицировал ли Google конкретный URL-адрес как известную угрозу.
- SafetyNet reCAPTCHA API. Эта служба включает API reCAPTCHA, который вы можете использовать для защиты своего приложения от таких угроз, как спам и вредоносный трафик. Если API подозревает, что ваше приложение взаимодействует с ботом, он предоставит CAPTCHA, которую получатель должен решить, прежде чем он сможет продолжить использование вашего приложения.
- SafetyNet Verify Apps API. Если ваше приложение содержит конфиденциальные данные пользователя, то вы можете использовать этот API для взаимодействия с устройством Verify Apps функцией и проверьте, является ли устройство свободного от вредоносных приложений. Если устройство небезопасно, вы можете ограничить ущерб, отключив все важные функции вашего приложения. Просто имейте в виду, что хотя SafetyNet будет предупреждать пользователей о любых обнаруженных потенциально вредоносных приложениях, нет никакой гарантии, что пользователь действительно удалит эти приложения. Кроме того, все время выпускаются вредоносные приложения, и хакеры всегда придумывают новые и изобретательные способы ускользнуть от внимания, поэтому даже если устройство проходит тест SafetyNet, вы не должны предполагать, что на нем нет вредоносных приложений. Устройство.
Дополнительные сведения об API-интерфейсах SafetyNet, в том числе инструкции по их использованию в приложениях, см. В официальной документации Android.
Используйте Android Protected Confirmation для конфиденциальных транзакций
Если вашему приложению необходимо выполнить конфиденциальную транзакцию, например произвести платеж, вы можете использовать Android Protected Confirmation на устройствах под управлением Android 9 (уровень API 28) или выше.
Каждый раз, когда пользователь пытается выполнить конфиденциальную транзакцию, Android Protected Confirmation будет отображать запрос с просьбой принять короткое заявление. Если пользователь одобряет это заявление, вы можете подписать сообщение, используя ключ из Android Keystore.
Для получения дополнительной информации, а также инструкций по внедрению Android Protected Confirmation ознакомьтесь с официальной документацией Android.
Android 10: запускать встроенный код DEX напрямую
На устройствах под управлением Android 10 (уровень API 29) и выше можно запускать встроенный код DEX непосредственно из APK-файла вашего приложения, что может помочь предотвратить атаку, даже если хакеру удастся вмешаться в локально скомпилированный код устройства.
Читайте также: Изучение Android Q: Добавление пузырьковых уведомлений в ваше приложение
Чтобы включить эту новую функцию безопасности, откройте манифест проекта и добавьте следующее в элемент :
<?xml version="1.0" encoding="utf-8"?>
Затем вам необходимо создать файл APK, содержащий несжатый код DEX, к которому ART может получить доступ напрямую. Откройте файл build.gradle и добавьте следующее:
aaptOptions {
noCompress
Просто имейте в виду, что ART будет использовать JIT-компилятор при запуске вашего приложения, что может повлиять на производительность вашего приложения.
Подведение итогов
В этой статье мы рассмотрели все передовые практики, инструменты, API и методы, которые вы можете использовать для обеспечения безопасности вашего приложения Android.
У вас есть какие-нибудь советы по повышению безопасности вашего приложения? Обязательно поделитесь своими советами в комментариях ниже!
Источник записи: https://www.androidauthority.com