18 мая 2020
5 372
Android разработка, Безопасность
Создание безопасных мобильных приложений — это первоочередная задача для большинства разработчиков, поскольку важно сохранять доверие пользователей и целостность данных. В этой статье мы познакомимся с некоторыми рекомендациями, которые следует соблюдать при создании Android приложений, чтобы не допускать уязвимостей.
A. Используйте неявные Intent, чтобы показывался экран, с помощью которого пользователь сможет выбрать одно из нескольких приложений для дальнейшего действия. Это позволит пользователям передавать конфиденциальную информацию тому приложению, которому они доверяют.
Б. Используйте разрешения на основе подписей при обмене данными между двумя вашими приложениями. Такие разрешения не требуют дополнительных подтверждений от пользователя. Вместо этого происходит проверка того, что приложения, которые обращаются к данным, подписаны с помощью одного и того же ключа. Следовательно, для пользователя всё выглядит проще и безопаснее.
1 2 3 4 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <permission android:name="my_custom_permission_name" android:protectionLevel="signature" /> |
C. Неэкспортируемые поставщики контента. Если вы не собираетесь делиться данными с другими приложениями, явно запретите им обращаться к вашему ContentProvider, прописав в манифесте android:exported=»false» (по умолчанию «true» для версий Android ниже 4.4).
Обеспечьте безопасность сетевых соединений с помощью HTTPS и SSL — для любых сетевых запросов, используйте HTTPS (вместо обычного HTTP) с правильно настроенными сертификатами. Подробнее смотрите здесь.
Безопасное соединение с сервером можно настроить следующими способами:
А. Для взаимодействия с веб-сервером, у которого настроен сертификат от известного доверенного центра, дополнительные действия при выполнении HTTP-запросов не требуются.
1 2 3 4 5 6 | val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use { ... } |
Б. Добавив конфигурацию сетевой безопасности: если ваше приложение использует новые или пользовательские центры сертификации, можно задать собственные настройки сетевой безопасности в конфигурационном файле. Это позволит вам создать конфигурацию не изменяя код приложения.
Чтобы добавить файл конфигурации в приложение, нужно сделать следующее:
i) Пропишите конфигурацию в манифесте приложения:
1 2 3 4 5 6 7 | <manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > <!-- Place child elements of <application> element here. --> </application> </manifest> |
ii) Создайте XML-файл ресурсов res/xm/network_security_config.xml.
Укажите, что весь обмен данными с соответствующими доменами должен производиться только по HTTPS, отключив незащищённые сетевые взаимодействия:
1 2 3 4 5 6 | <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> ... </domain-config> </network-security-config> |
В процессе разработки можно использовать элемент <debug-overrides>, чтобы явно разрешить пользовательские сертификаты. Этот элемент переопределяет критически важные параметры сетевой безопасности при отладке и тестировании приложения, не влияя на релизную конфигурацию. Следующий отрывок кода показывает, как использовать этот элемент в XML-файле конфигурации сетевой безопасности:
1 2 3 4 5 6 7 | <network-security-config> <debug-overrides> <trust-anchors> <certificates src="user" /> </trust-anchors> </debug-overrides> </network-security-config> |
В. Создайте собственный доверительный менеджер, если веб-сервер использует сертификат, подписанный новым или пользовательским центром сертификации, которому не доверяет мобильное устройство и при этом нет возможности задать конфигурацию сетевой безопасности.
В таком случае потребуется настроить доверительный менеджер и обрабатывать все предупреждения, возникающие в SSL.
Г. Привязка сертификатов. Можно настроить приложение на работу только с определённым набором сертификатов путем ограничения списка доверенных центров сертификации или же с помощью привязки сертификатов.
Это достигается путем предоставления набора сертификатов с помощью хэша открытого ключа (SubjectPublicKeyInfo для сертификата X.509). При таком подходе цепочка сертификатов пройдёт проверку успешно только в том случае, если будет содержать хотя бы один из предоставленных открытых ключей.
Другие сценарии: есть ещё несколько моментов, которые следует учитывать при получении вашим приложением доступа к данным через Интернет:
Приложение должно запрашивать лишь минимум разрешений, необходимый для его корректной работы.
Не следует добавлять разрешения для действий, которые могут быть выполнены в другом приложении. Вместо этого используйте Intent, чтобы делегировать действие другому приложению, уже имеющему необходимое разрешение.
На пример, если вашему приложению нужно добавить контакт, то делегируйте это действие приложению Контакты, у которого уже есть соответствующее разрешение WRITE_CONTACTS.
Криптография является наиболее эффективным способом обеспечить безопасность данных. Поэтому, используйте подходящий механизм шифрования, при работе с данными в приложении. Для достижения большей безопасности ключей используйте систему Android Keystore. Хорошую статью о шифровании можно прочитать здесь.
Ниже приведены рекомендации по хранению данных на устройстве.
А. Храните личные данные во внутреннем хранилище
Храните все личные данные пользователей во внутреннем хранилище устройства, которое изолировано от других приложений. Для доступа к этим файлам не нужно запрашивать разрешение, но другим приложениям такие файлы недоступны. Если пользователь удалит приложение, то все файлы, которые приложение сохраняло во внутреннее хранилище, также будут удалены. Кроме того, рассмотрите вариант использования EncryptedFile из библиотеки Security, вместо объектов File.
Б. Осторожно используйте внешнее хранилище
По умолчанию Android не применяет ограничения безопасности для данных, которые находятся во внешнем хранилище. Также не гарантируется, что сам носитель данных будет всё время подключен к устройству. Поэтому для обеспечения безопасности при доступе к информации из внешнего хранилища примите следующие меры:
Используйте ограниченный доступ к директориям: если приложению нужно обращаться лишь к определенной директории во внешнем хранилище устройства, то используйте область видимости, тем самым ограничив вашему приложению доступ к внешнему хранилищу устройства.
Файлы, связанные с приложением: если файл не содержит персональную или конфиденциальную информацию, но является значимым для пользователя только в контексте вашего приложения, то храните файл в директории конкретного приложения во внешнем хранилище.
В. Храните неконфиденциальные данные в файлах кэша
Для предоставления быстрого доступа к неконфиденциальным данным приложения храните их в кэше устройства. Если размер кэша превышает 1 Мб, то используйте getExternalCacheDir(). В противном случае используйте getCacheDir(). Оба метода вернут вам объект File, который содержит закэшированные данные приложения.
Г. Используйте SharedPreferences в приватном режиме
Используйте MODE_PRIVATE при создании и получении объектов SharedPreferences с помощью getSharedPreferences(), чтобы ваше приложение смогло получить информацию из файла общих настроек.
Кроме того, для усиления безопасности следует использовать EncryptedSharedPreferences, который оборачивает класс SharedPreferences и автоматически шифрует ключи и значения.
Если вы собираете проект с помощью Android Gradle 3.4.0 или более поздней версии, то в данном плагине больше не используется ProGuard для оптимизации кода во время компиляции. Вместо этого задействуется компилятор R8, чтобы во время компиляции выполнить следующие задачи:
Данным рекомендациям должен следовать каждый разработчик, чтобы защитить свои мобильные приложения от уязвимостей. Они помогут разрабатывать приложения с высокой степенью защиты, которые предотвратят утечки ценной пользовательской информации и позволят сохранить доверие клиентов.
Оригинал статьи: тут
Размещение библиотеки через JCenter и Maven Central при помощи Android Studio
19 февраля 2018 17 831
Как работать с негативными отзывами в Google Play
20 декабря 2023 434
Обеспечение безопасности в Androind приложениях
24 марта 2020 3 659
16 января 2018 16 962