Контрольный список мер по обеспечению безопасности

Android имеет встроенные функции безопасности, которые значительно снижают частоту и влияние проблем безопасности приложений. Система спроектирована таким образом, что вы обычно можете создавать свои приложения с системными и файловыми разрешениями по умолчанию и избегать сложных решений по поводу безопасности.

Следующие основные функции безопасности помогут вам создавать безопасные приложения:

  • Песочница приложения Android, которая изолирует данные вашего приложения и выполнение кода от других приложений.
  • Платформа приложений с надежной реализацией общих функций безопасности, таких как криптография, разрешения и безопасное межпроцессное взаимодействие (IPC).
  • Такие технологии, как рандомизация макета адресного пространства (ASLR) , no-execute (NX) , ProPolice, Safe_iop , OpenBSD dlmalloc и calloc и Linux mmap_min_addr для снижения рисков, связанных с распространенными ошибками управления памятью.
  • Предоставляемые пользователем разрешения для ограничения доступа к функциям системы и пользовательским данным.
  • Разрешения, определяемые приложением, для управления данными приложения отдельно для каждого приложения.

Важно ознакомиться с рекомендациями по обеспечению безопасности Android, представленными на этой странице. Следование этим правилам в качестве общих привычек программирования поможет вам избежать непреднамеренного возникновения проблем безопасности, которые отрицательно влияют на ваших пользователей.

Аутентификация

Аутентификация является обязательным условием для многих ключевых операций безопасности. Чтобы контролировать доступ к защищенным ресурсам, таким как пользовательские данные, функции приложения и другие ресурсы, вам необходимо добавить аутентификацию в свое приложение Android.

Вы можете улучшить процесс аутентификации вашего пользователя, интегрировав свое приложение с Credential Manager . Диспетчер учетных данных — это библиотека Android Jetpack, которая объединяет поддержку API для большинства основных методов аутентификации, включая ключи доступа, пароли и решения для федеративного входа, такие как вход с Google .

Чтобы еще больше повысить безопасность вашего приложения, рассмотрите возможность добавления методов биометрической аутентификации, таких как сканирование отпечатков пальцев или распознавание лиц. Хорошими кандидатами для добавления биометрической аутентификации могут быть приложения для финансов, здравоохранения или управления идентификацией.

Платформа автозаполнения Android может упростить процесс регистрации и входа в систему, уменьшая количество ошибок и неудобств для пользователей. Автозаполнение интегрируется с менеджерами паролей, позволяя пользователям выбирать сложные случайные пароли, которые можно легко и безопасно хранить и извлекать.

Целостность приложения

Play Integrity API помогает вам проверить, что взаимодействия и запросы к серверу поступают из подлинного двоичного файла приложения, работающего на подлинном устройстве Android. Обнаруживая потенциально рискованные и мошеннические взаимодействия, например, из поддельных версий приложений и ненадежных сред, внутренний сервер вашего приложения может отреагировать соответствующими действиями для предотвращения атак и сокращения злоупотреблений.

Хранение данных

Наиболее распространенной проблемой безопасности приложения на Android является то, доступны ли данные, которые вы сохраняете на устройстве, другим приложениям. Существует три основных способа сохранить данные на устройстве:

  • Внутреннее хранилище
  • Внешнее хранилище
  • Поставщики контента

В следующих разделах описываются проблемы безопасности, связанные с каждым подходом.

Внутреннее хранилище

По умолчанию файлы, которые вы создаете во внутренней памяти, доступны только вашему приложению. В Android реализована такая защита, и ее достаточно для большинства приложений.

Избегайте устаревших режимов MODE_WORLD_WRITEABLE и MODE_WORLD_READABLE для файлов IPC. Они не предоставляют возможности ограничить доступ к данным для определенных приложений и не обеспечивают никакого контроля над форматом данных. Если вы хотите поделиться своими данными с другими процессами приложения, рассмотрите возможность использования вместо этого поставщика контента , который предлагает разрешения на чтение и запись другим приложениям и может предоставлять динамические разрешения в каждом конкретном случае.

Внешнее хранилище

Файлы, созданные на внешнем накопителе , например на SD-картах, доступны для чтения и записи во всем мире. Поскольку внешнее хранилище может быть удалено пользователем, а также изменено любым приложением, сохраняйте только неконфиденциальную информацию, используя внешнее хранилище.

Выполняйте проверку входных данных при обработке данных из внешнего хранилища так же, как и при работе с данными из любого ненадежного источника. Не храните исполняемые файлы или файлы классов на внешнем хранилище до динамической загрузки. Если ваше приложение получает исполняемые файлы из внешнего хранилища, перед динамической загрузкой убедитесь, что файлы подписаны и криптографически проверены.

Поставщики контента

Поставщики контента предлагают структурированный механизм хранения, который можно ограничить вашим собственным приложением или экспортировать, чтобы обеспечить доступ другим приложениям. Если вы не собираетесь предоставлять другим приложениям доступ к вашему ContentProvider , отметьте его как android:exported=false в манифесте приложения. В противном случае установите для атрибута android:exported значение true , чтобы другие приложения могли получить доступ к сохраненным данным.

При создании ContentProvider , который экспортируется для использования другими приложениями, вы можете указать одно разрешение на чтение и запись или указать отдельные разрешения на чтение и запись. Ограничьте свои разрешения теми, которые необходимы для выполнения поставленной задачи. Имейте в виду, что обычно легче добавить разрешения позже, чтобы предоставить новые функции, чем отобрать их и повлиять на существующих пользователей.

Если вы используете поставщика контента для обмена данными только между вашими приложениями, мы рекомендуем использовать атрибут android:protectionLevel для которого задана защита signature . Разрешения на подпись не требуют подтверждения пользователя, поэтому они обеспечивают лучший пользовательский опыт и более контролируемый доступ к данным поставщика контента, когда приложения, обращающиеся к данным, подписаны одним и тем же ключом.

Поставщики контента также могут обеспечить более детальный доступ, объявив атрибут android:grantUriPermissions и используя флаги FLAG_GRANT_READ_URI_PERMISSION и FLAG_GRANT_WRITE_URI_PERMISSION в объекте Intent , который активирует компонент. Объем этих разрешений может быть дополнительно ограничен элементом <grant-uri-permission> .

При доступе к поставщику контента используйте методы параметризованных запросов, такие как query , update и delete() , чтобы избежать потенциального внедрения SQL из ненадежных источников. Обратите внимание, что использования параметризованных методов недостаточно, если аргумент selection создается путем объединения пользовательских данных перед их отправкой в ​​метод.

Не испытывайте ложного чувства безопасности по поводу разрешения на запись. Разрешение на запись позволяет использовать операторы SQL, которые позволяют подтверждать некоторые данные с помощью креативных предложений WHERE и анализировать результаты. Например, злоумышленник может проверить наличие определенного номера телефона в журнале вызовов, изменив строку, только если этот номер телефона уже существует. Если данные поставщика контента имеют предсказуемую структуру, разрешение на запись может быть эквивалентно предоставлению как чтения, так и записи.

Разрешения

Поскольку Android изолирует приложения друг от друга, приложения должны явно совместно использовать ресурсы и данные. Они делают это, объявляя разрешения, необходимые для дополнительных возможностей, не предоставляемых базовой песочницей, включая доступ к функциям устройства, таким как камера.

Запросы на разрешение

Минимизируйте количество разрешений, запрашиваемых вашим приложением. Ограничение доступа к конфиденциальным разрешениям снижает риск непреднамеренного неправильного использования этих разрешений, улучшает принятие пользователями и делает ваше приложение менее уязвимым для злоумышленников. Как правило, если для работы вашего приложения не требуется разрешение, не запрашивайте его. См. руководство по оценке того, нужно ли вашему приложению объявлять разрешения .

Если возможно, создавайте свое приложение так, чтобы не требовалось никаких разрешений. Например, вместо того, чтобы запрашивать доступ к информации об устройстве для создания уникального идентификатора, создайте UUID для своего приложения. (Подробнее читайте в разделе о пользовательских данных ). Или вместо использования внешнего хранилища (для чего требуется разрешение) храните данные во внутреннем хранилище.

Помимо запроса разрешений, ваше приложение может использовать элемент <permission> для защиты IPC, который чувствителен к безопасности и доступен другим приложениям, таким как ContentProvider . В общем, мы рекомендуем там, где это возможно, использовать элементы управления доступом, отличные от разрешений, подтвержденных пользователем, поскольку разрешения могут сбивать пользователей с толку. Например, рассмотрите возможность использования уровня защиты подписи для разрешений на обмен данными IPC между приложениями, предоставляемыми одним разработчиком.

Не допускайте утечки данных, защищенных разрешениями. Это происходит, когда ваше приложение предоставляет данные через IPC, которые доступны только потому, что у вашего приложения есть разрешение на доступ к этим данным. Клиенты интерфейса IPC вашего приложения могут не иметь такого же разрешения на доступ к данным. Более подробная информация о частоте и потенциальных последствиях этой проблемы содержится в исследовательской статье Permission Re-Delegation: Attacks and Defenses , опубликованной на USENIX.

Определения разрешений

Определите наименьший набор разрешений, отвечающий вашим требованиям безопасности. Создание нового разрешения является относительно редкой задачей для большинства приложений, поскольку определяемые системой разрешения охватывают множество ситуаций. При необходимости выполните проверки доступа, используя существующие разрешения.

Если вам нужно новое разрешение, подумайте, сможете ли вы выполнить свою задачу с уровнем защиты подписи . Разрешения на подпись прозрачны для пользователя и разрешают доступ только приложениям, подписанным тем же разработчиком, что и приложение, выполняющее проверку разрешений.

Если создание нового разрешения по-прежнему требуется, объявите его в манифесте приложения с помощью элемента <permission> . Приложения, использующие новое разрешение, могут ссылаться на него, добавив элемент <uses-permission> в свои файлы манифеста. Вы также можете добавлять разрешения динамически, используя метод addPermission() .

Если вы создаете разрешение с опасным уровнем защиты, необходимо учитывать ряд сложностей:

  • Разрешение должно содержать строку, которая кратко выражает пользователю решение по безопасности, которое он должен принять.
  • Строка разрешения должна быть локализована на множество разных языков.
  • Пользователи могут отказаться устанавливать приложение, поскольку разрешение сбивает с толку или воспринимается как рискованное.
  • Приложения могут запрашивать разрешение, если создатель разрешения не установлен.

Каждый из них представляет собой значительную нетехническую проблему для вас как разработчика, а также сбивает с толку ваших пользователей, поэтому мы не рекомендуем использовать опасный уровень разрешений.

сеть

Сетевые транзакции по своей сути представляют риск для безопасности, поскольку они включают в себя передачу данных, которые потенциально являются конфиденциальными для пользователя. Люди все больше осознают проблемы конфиденциальности мобильного устройства, особенно когда устройство выполняет сетевые транзакции, поэтому очень важно, чтобы в вашем приложении применялись все лучшие практики для постоянного обеспечения безопасности данных пользователя.

IP-сети

Сеть на Android существенно не отличается от других сред Linux. Ключевым моментом является обеспечение использования соответствующих протоколов для конфиденциальных данных, таких как HttpsURLConnection для безопасного веб-трафика. Используйте HTTPS вместо HTTP везде, где HTTPS поддерживается на сервере, поскольку мобильные устройства часто подключаются к незащищенным сетям, например к общедоступным точкам доступа Wi-Fi.

Аутентифицированную и зашифрованную связь на уровне сокетов можно легко реализовать с помощью класса SSLSocket . Учитывая частоту, с которой устройства Android подключаются к незащищенным беспроводным сетям с помощью Wi-Fi, настоятельно рекомендуется использовать безопасные сети для всех приложений, которые обмениваются данными по сети.

Некоторые приложения используют сетевые порты локального хоста для обработки конфиденциальных IPC. Не используйте этот подход, поскольку эти интерфейсы доступны другим приложениям на устройстве. Вместо этого используйте механизм Android IPC, где возможна аутентификация, например с помощью Service . Привязка к неспецифическому IP-адресу INADDR_ANY хуже, чем использование обратной связи, поскольку позволяет вашему приложению получать запросы с любого IP-адреса.

Убедитесь, что вы не доверяете данным, загруженным по HTTP или другим небезопасным протоколам. Сюда входит проверка ввода в WebView и любые ответы на намерения, выданные по протоколу HTTP.

Телефонная сеть

Протокол службы коротких сообщений (SMS) был в первую очередь разработан для общения между пользователями и не очень подходит для приложений, которым требуется передача данных. Из-за ограничений SMS мы рекомендуем использовать Firebase Cloud Messaging (FCM) и IP-сети для отправки сообщений с данными с веб-сервера в ваше приложение на пользовательском устройстве.

Имейте в виду, что SMS не зашифрованы и не проходят строгую проверку подлинности ни в сети, ни на устройстве. В частности, любой получатель SMS должен ожидать, что злонамеренный пользователь мог отправить SMS в ваше приложение. Не полагайтесь на неаутентифицированные данные SMS для выполнения конфиденциальных команд. Также имейте в виду, что SMS могут быть подделаны и/или перехвачены в сети. На самом устройстве под управлением Android SMS-сообщения передаются как широковещательные намерения, поэтому их можно прочитать или перехватить другими приложениями, имеющими разрешение READ_SMS .

Проверка ввода

Недостаточная проверка входных данных — одна из наиболее распространенных проблем безопасности, затрагивающих приложения, независимо от того, на какой платформе они работают. В Android предусмотрены контрмеры на уровне платформы, которые снижают подверженность приложений проблемам с проверкой ввода, и мы рекомендуем вам использовать эти функции, где это возможно. Кроме того, мы рекомендуем использовать типобезопасные языки, чтобы снизить вероятность проблем с проверкой ввода.

Если вы используете собственный код, любые данные, считанные из файлов, полученные по сети или полученные от IPC, могут создать проблему безопасности. Наиболее распространенными проблемами являются переполнение буфера , использование после free и ошибки отключения на единицу . Android предоставляет ряд технологий, таких как ASLR и Data Execution Prevention (DEP), которые снижают вероятность использования этих ошибок, но не решают основную проблему. Вы можете предотвратить эти уязвимости, тщательно обрабатывая указатели и управляя буферами.

Динамические строковые языки, такие как JavaScript и SQL, также подвержены проблемам с проверкой ввода из-за escape-символов и внедрения скриптов .

Если вы используете данные в запросах, отправляемых в базу данных SQL или поставщику контента, внедрение SQL может стать проблемой. Лучшая защита — использование параметризованных запросов, как описано в разделе о поставщиках контента . Ограничение разрешений только для чтения или только для записи также может снизить потенциальный вред, связанный с внедрением SQL.

Если вы не можете использовать функции безопасности, описанные в этом разделе, обязательно используйте хорошо структурированные форматы данных и убедитесь, что данные соответствуют ожидаемому формату. Хотя блокировка определенных символов или замена символов может быть эффективной стратегией, на практике эти методы подвержены ошибкам, и мы рекомендуем по возможности избегать их.

Пользовательские данные

Лучший подход к обеспечению безопасности пользовательских данных — свести к минимуму использование API-интерфейсов, которые получают доступ к конфиденциальной или личной информации. Если у вас есть доступ к пользовательским данным, по возможности избегайте их хранения или передачи. Подумайте, можно ли реализовать логику вашего приложения с использованием хеш- или необратимой формы данных. Например, ваше приложение может использовать хэш адреса электронной почты в качестве первичного ключа, чтобы избежать передачи или хранения адреса электронной почты. Это снижает вероятность непреднамеренного раскрытия данных, а также снижает вероятность того, что злоумышленники попытаются использовать ваше приложение.

Аутентифицируйте своего пользователя всякий раз, когда требуется доступ к личным данным, и используйте современные методы аутентификации, такие как ключи доступа и диспетчер учетных данных . Если вашему приложению необходим доступ к личной информации, имейте в виду, что в некоторых юрисдикциях от вас может потребоваться предоставление политики конфиденциальности, объясняющей использование и хранение этих данных. Следуйте рекомендациям по обеспечению безопасности, минимизируя доступ к пользовательским данным, чтобы упростить соблюдение требований.

Кроме того, подумайте, может ли ваше приложение случайно раскрыть личную информацию другим лицам, например сторонним компонентам для рекламы или сторонним службам, используемым вашим приложением. Если вы не знаете, почему компонент или служба требуют личной информации, не предоставляйте ее. В целом, ограничение доступа вашего приложения к личной информации снижает вероятность возникновения проблем в этой области.

Если вашему приложению требуется доступ к конфиденциальным данным, оцените, нужно ли вам передавать их на сервер или вы можете запустить операцию на клиенте. Рассмотрите возможность запуска любого кода, использующего конфиденциальные данные на клиенте, чтобы избежать передачи пользовательских данных. Кроме того, убедитесь, что вы случайно не раскрываете пользовательские данные другим приложениям на устройстве через чрезмерно разрешающий IPC, файлы, доступные для записи всем пользователям, или сетевые сокеты. Чрезмерно разрешительный IPC — это особый случай утечки данных, защищенных разрешениями, который обсуждается в разделе «Запросы разрешений» .

Если требуется глобальный уникальный идентификатор (GUID), создайте большой уникальный номер и сохраните его. Не используйте идентификаторы телефона, такие как номер телефона или IMEI, которые могут быть связаны с личной информацией. Более подробно эта тема обсуждается на странице о лучших практиках использования уникальных идентификаторов .

Будьте осторожны при записи в журналы на устройстве. В Android журналы являются общим ресурсом и доступны приложению с разрешением READ_LOGS . Несмотря на то, что данные журнала телефона являются временными и удаляются при перезагрузке, ненадлежащая регистрация пользовательской информации может привести к непреднамеренной утечке пользовательских данных в другие приложения. Помимо запрета регистрации личных данных, ограничьте использование журналов в рабочих приложениях. Чтобы легко реализовать это, используйте флаги отладки и специальные классы Log с легко настраиваемыми уровнями журналирования.

Веб-представление

Поскольку WebView использует веб-содержимое, которое может включать HTML и JavaScript, неправильное использование может привести к возникновению распространенных проблем веб-безопасности, таких как межсайтовый скриптинг (внедрение JavaScript). Android включает в себя ряд механизмов, позволяющих уменьшить масштаб этих потенциальных проблем, ограничивая возможности WebView минимальными функциями, необходимыми вашему приложению.

Если ваше приложение не использует JavaScript напрямую внутри WebView , не вызывайте setJavaScriptEnabled . В некоторых примерах кода используется этот метод; Если вы переназначаете пример кода, который использует его в рабочем приложении, удалите этот вызов метода, если он не требуется. По умолчанию WebView не выполняет JavaScript, поэтому межсайтовый скриптинг невозможен.

Используйте addJavaScriptInterface() с особой осторожностью, поскольку он позволяет JavaScript вызывать операции, которые обычно зарезервированы для приложений Android. Если вы его используете, предоставляйте доступ к addJavaScriptInterface() только тем веб-страницам, все входные данные которых заслуживают доверия. Если разрешен ненадежный ввод, ненадежный JavaScript может вызывать методы Android в вашем приложении. В общем, мы рекомендуем использовать addJavaScriptInterface() только для JavaScript, который содержится в APK вашего приложения.

Если ваше приложение обращается к конфиденциальным данным с помощью WebView , рассмотрите возможность использования clearCache() для удаления любых файлов, хранящихся локально. Вы также можете использовать заголовки на стороне сервера, например no-store , чтобы указать, что приложение не должно кэшировать определенный контент.

Устройства под управлением платформ старше Android 4.4 (уровень API 19) используют версию webkit , имеющую ряд проблем с безопасностью. В качестве обходного пути: если ваше приложение работает на этих устройствах, оно должно подтвердить, что объекты WebView отображают только доверенный контент. Чтобы убедиться, что ваше приложение не подвержено потенциальным уязвимостям SSL, используйте обновляемый объект Provider безопасности, как описано в разделе Обновление поставщика безопасности для защиты от эксплойтов SSL . Если ваше приложение должно отображать контент из открытого Интернета, рассмотрите возможность использования собственного средства визуализации, чтобы вы могли обновлять его с помощью последних обновлений безопасности.

Запросы учетных данных

Запросы учетных данных являются вектором атаки. Вот несколько советов, которые помогут вам сделать запросы учетных данных в приложениях Android более безопасными.

Минимизируйте раскрытие учетных данных

  • Избегайте ненужных запросов учетных данных . Чтобы сделать фишинговые атаки более заметными и менее вероятными, сведите к минимуму частоту запроса учетных данных пользователя. Вместо этого используйте токен авторизации и обновите его. Запрашивайте только минимальный объем учетной информации, необходимой для аутентификации и авторизации.
  • Надежно храните учетные данные . Используйте диспетчер учетных данных , чтобы включить проверку подлинности без пароля с использованием ключей доступа или реализовать федеративный вход с использованием таких схем, как «Войти через Google». Если вам необходимо использовать традиционную аутентификацию по паролю, не храните идентификаторы пользователей и пароли на устройстве. Вместо этого выполните первоначальную аутентификацию с использованием имени пользователя и пароля, предоставленных пользователем, а затем используйте недолговечный токен авторизации для конкретной службы.
  • Ограничьте объем разрешений . Не запрашивайте широкие разрешения для задачи, которая требует только более узкой области действия.
  • Ограничить токены доступа . Используйте кратковременные операции с токенами и вызовы API.
  • Ограничьте скорость аутентификации . Быстрые и последовательные запросы аутентификации или авторизации могут быть признаком грубой атаки. Ограничьте эти ставки разумной частотой, сохраняя при этом функциональную и удобную для пользователя работу приложения.

Используйте безопасную аутентификацию

  • Внедрить ключи доступа . Включите ключи доступа как более безопасное и удобное обновление паролей.
  • Добавьте биометрию . Предложите возможность использовать биометрическую аутентификацию , такую ​​как отпечаток пальца или распознавание лица, для дополнительной безопасности.
  • Используйте федеративные поставщики удостоверений . Диспетчер учетных данных поддерживает поставщиков федеративной аутентификации, таких как «Вход через Google» .
  • Шифрование связи. Используйте HTTPS и аналогичные технологии, чтобы обеспечить защиту данных, которые ваше приложение отправляет по сети.

Практикуйте безопасное управление учетными записями

  • Подключайтесь к службам, доступным нескольким приложениям, с помощью AccountManager . Используйте класс AccountManager для вызова облачной службы и не храните пароли на устройстве.
  • После использования AccountManager для получения Account используйте CREATOR перед передачей каких-либо учетных данных, чтобы случайно не передать учетные данные не тому приложению.
  • Если учетные данные используются только созданными вами приложениями, вы можете проверить приложение, которое обращается к AccountManager с помощью checkSignatures . Альтернативно, если учетные данные использует только одно приложение, вы можете использовать KeyStore для хранения.

Будьте бдительны

  • Поддерживайте свой код в актуальном состоянии . Обязательно обновите исходный код, включая любые сторонние библиотеки и зависимости, чтобы защититься от новейших уязвимостей.
  • Отслеживайте подозрительную активность . Ищите потенциальные злоупотребления, например, примеры неправильного использования авторизации.
  • Проведите аудит своего кода . Выполняйте регулярные проверки безопасности вашей кодовой базы на предмет потенциальных проблем с запросом учетных данных.

Управление ключами API

Ключи API являются важнейшим компонентом многих приложений Android, позволяя им получать доступ к внешним службам и выполнять важные функции, такие как подключение к картографическим службам, аутентификация и метеорологические службы. Однако раскрытие этих конфиденциальных ключей может иметь серьезные последствия, включая утечку данных, несанкционированный доступ и финансовые потери. Чтобы предотвратить подобные сценарии, разработчикам следует реализовать безопасные стратегии обработки ключей API на протяжении всего процесса разработки.

Чтобы защитить сервисы от неправомерного использования, ключи API должны быть тщательно защищены. Чтобы защитить соединение между приложением и сервисом, использующим ключ API, вам необходимо защитить доступ к API. Когда ваше приложение скомпилировано и исходный код вашего приложения содержит ключи API, злоумышленник может декомпилировать приложение и найти эти ресурсы.

Этот раздел предназначен для двух групп разработчиков Android: тех, кто работает с инфраструктурными командами над конвейером непрерывной доставки, и тех, кто развертывает автономные приложения в магазине Play. В этом разделе описываются лучшие практики обработки ключей API, чтобы ваше приложение могло безопасно взаимодействовать со службами.

Генерация и хранение

Разработчики должны рассматривать хранилище ключей API как важнейший компонент защиты данных и конфиденциальности пользователей, используя подход глубокоэшелонированной защиты.

Надежное хранилище ключей

Для оптимальной безопасности управления ключами используйте Android Keystore и зашифруйте сохраненные ключи с помощью надежного инструмента, такого как Tink Java .

Исключение из системы контроля версий

Никогда не сохраняйте ключи API в хранилище исходного кода. Добавление ключей API в исходный код может привести к тому, что ключи попадут в общедоступные репозитории, примеры общего кода и случайно переданные файлы. Вместо этого используйте плагины Gradle, такие как secrets-gradle-plugin, для работы с ключами API в вашем проекте.

Ключи, зависящие от среды

Если возможно, используйте отдельные среды разработки, тестирования и производства ключей API. Используйте ключи, специфичные для среды, для изоляции каждой среды, снижая риск раскрытия производственных данных и позволяя отключать скомпрометированные ключи, не затрагивая вашу производственную среду.

Контроль использования и доступа

Практика безопасного использования ключей API необходима для защиты вашего API и ваших пользователей. Вот как подготовить ключи для обеспечения оптимальной безопасности:

  • Создавайте уникальные ключи для каждого приложения . Используйте отдельные ключи API для каждого приложения, чтобы выявить и изолировать скомпрометированный доступ.
  • Внедрить ограничения IP . Если возможно, ограничьте использование ключа API определенными IP-адресами или диапазонами.
  • Ограничьте использование ключа мобильного приложения . Ограничьте использование ключа API определенными мобильными приложениями, связав их с ключом или используя сертификаты приложений.
  • Регистрируйте и отслеживайте подозрительную активность . Внедрите механизмы регистрации и мониторинга использования API для обнаружения подозрительной активности и предотвращения потенциальных злоупотреблений.

Примечание . Ваш сервис должен предоставлять функции для ограничения ключей определенным пакетом или платформой. Например, API Карт Google ограничивает доступ к ключу по имени пакета и ключу подписи.

OAuth 2.0 предоставляет основу для авторизации доступа к ресурсам. Он определяет стандарты взаимодействия клиентов и серверов и обеспечивает безопасную авторизацию. Вы можете использовать OAuth 2.0, чтобы ограничить использование ключей API конкретными клиентами и определить область доступа, чтобы каждый ключ API имел только минимальный уровень доступа, необходимый для его предполагаемой цели.

Ротация и срок действия ключей

Чтобы снизить риск несанкционированного доступа через необнаруженные уязвимости API, важно регулярно менять ключи API. Стандарт ISO 27001 определяет структуру соответствия частоте ротации ключей. В большинстве случаев период ротации ключей от 90 дней до 6 месяцев должен быть достаточным. Внедрение надежной системы управления ключами может помочь вам оптимизировать эти процессы, повышая эффективность ротации ключей и увеличения срока их действия.

Общие рекомендации

  • Использовать SSL/HTTPS : всегда используйте HTTPS-связь для шифрования запросов API.
  • Закрепление сертификата . Для дополнительного уровня безопасности вы можете рассмотреть возможность закрепления сертификата, чтобы проверить, какие сертификаты считаются действительными.
  • Проверка и очистка пользовательского ввода . Проверяйте и очищайте пользовательский ввод, чтобы предотвратить атаки путем внедрения, которые могут раскрыть ключи API.
  • Следуйте рекомендациям по безопасности . Внедряйте общие рекомендации по безопасности в процесс разработки, включая методы безопасного кодирования, проверки кода и сканирование уязвимостей.
  • Будьте в курсе : будьте в курсе последних угроз безопасности и лучших практик управления ключами API.
  • Обновления SDK . Убедитесь, что ваши SDK и библиотеки обновлены до последней версии.

Криптография

Помимо обеспечения изоляции данных, поддержки полного шифрования файловой системы и обеспечения безопасных каналов связи, Android предоставляет широкий спектр алгоритмов защиты данных с помощью криптографии.

Узнайте, какие поставщики безопасности Java Cryptography Architecture (JCA) использует ваше программное обеспечение. Попробуйте использовать самый высокий уровень уже существующей реализации платформы, которая может поддержать ваш вариант использования. Если применимо, используйте поставщиков, предоставленных Google, в указанном Google порядке.

Если вам необходимо безопасно получить файл из известного сетевого расположения, может оказаться достаточным простой URI HTTPS, не требующий знаний криптографии. Если вам нужен безопасный туннель, рассмотрите возможность использования HttpsURLConnection или SSLSocket а не написания собственного протокола. Если вы используете SSLSocket , имейте в виду, что он не выполняет проверку имени хоста. См . Предупреждения об использовании SSLSocket напрямую .

Если вы обнаружите, что вам необходимо реализовать собственный протокол, не внедряйте собственные криптографические алгоритмы. Используйте существующие криптографические алгоритмы, например реализации AES и RSA, представленные в классе Cipher . Кроме того, следуйте этим рекомендациям:

  • Используйте 256-битный AES в коммерческих целях. (Если недоступен, используйте 128-битный AES.)
  • Используйте открытый ключ длиной 224 или 256 бит для криптографии на основе эллиптических кривых (EC).
  • Знайте, когда использовать режимы блокировки CBC, CTR или GCM.
  • Избегайте повторного использования IV/счетчика в режиме CTR. Убедитесь, что они криптографически случайны.
  • При использовании шифрования реализуйте целостность, используя режим CBC или CTR с помощью одной из следующих функций:
    • HMAC-SHA1
    • HMAC-SHA-256
    • HMAC-SHA-512
    • Режим GCM

Используйте безопасный генератор случайных чисел SecureRandom для инициализации любых криптографических ключей, сгенерированных KeyGenerator . Использование ключа, который не сгенерирован с помощью безопасного генератора случайных чисел, значительно ослабляет надежность алгоритма и может сделать возможным автономные атаки.

Если вам необходимо сохранить ключ для повторного использования, используйте такой механизм, как KeyStore , который обеспечивает долгосрочное хранение и извлечение криптографических ключей.

Межпроцессное взаимодействие

Некоторые приложения пытаются реализовать IPC, используя традиционные методы Linux, такие как сетевые сокеты и общие файлы. Однако вместо этого мы рекомендуем использовать функции системы Android для IPC, такие как Intent , Binder или Messenger with a Service и BroadcastReceiver . Механизмы Android IPC позволяют вам проверять подлинность приложения, подключающегося к вашему IPC, и устанавливать политику безопасности для каждого механизма IPC.

Многие элементы безопасности являются общими для всех механизмов IPC. Если ваш механизм IPC не предназначен для использования другими приложениями, установите для атрибута android:exported значение false в элементе манифеста компонента, например, для элемента <service> . Это полезно для приложений, которые состоят из нескольких процессов с одним и тем же UID, или если на позднем этапе разработки вы решили, что на самом деле не хотите предоставлять функциональность как IPC, но не хотите переписывать код.

Если ваш IPC доступен другим приложениям, вы можете применить политику безопасности с помощью элемента <permission> . Если IPC используется между вашими собственными приложениями и подписанными одним и тем же ключом, используйте разрешение signature-level в android:protectionLevel .

Намерения

Для действий и получателей широковещательных сообщений намерения являются предпочтительным механизмом асинхронного IPC на Android. В зависимости от требований вашего приложения вы можете использовать sendBroadcast , sendOrderedBroadcast или явное намерение для конкретного компонента приложения. В целях безопасности предпочтительны явные намерения.

Внимание ! Если вы используете намерение для привязки к **Service** , используйте явное намерение, чтобы обеспечить безопасность вашего приложения. Использование неявного намерения запустить службу представляет собой угрозу безопасности, поскольку вы не можете быть уверены, какая служба отреагирует на это намерение, а пользователь не может видеть, какая служба запускается. Начиная с Android 5.0 (уровень API 21), система выдает исключение, если вы вызываете **bindService()** с неявным намерением.

Обратите внимание, что заказанные широковещательные рассылки могут быть использованы получателем, поэтому они могут не доставляться во все приложения. Если вы отправляете намерение, которое должно быть доставлено конкретному получателю, вы должны использовать явное намерение, которое объявляет получателя по имени.

Отправители намерения могут убедиться, что получатель имеет разрешение, указав не нулевое разрешение с вызовом метода. Только приложения с этого разрешения получают намерение. Если данные в рамках вещания могут быть чувствительными, рассмотрите возможность применения разрешения, чтобы убедиться, что вредоносные приложения не могут зарегистрироваться для получения этих сообщений без соответствующих разрешений. В этих обстоятельствах вы также можете рассмотреть вопрос о том, чтобы привлечь к получателю напрямую, а не поднять трансляцию.

Примечание . Фильтры намерения не являются функциями безопасности. Компоненты могут быть вызваны явными намерениями и могут не иметь данных, которые будут соответствовать фильтру намерения. Чтобы подтвердить, что он должным образом отформатирован для выдвинутого приемника, службы или деятельности, выполните проверку ввода в вашем приемнике.

Услуги

Service часто используется для поставки функциональности для других приложений для использования. Каждый класс службы должен иметь соответствующее объявление <service> в своем манифестном файле.

По умолчанию услуги не экспортируются и не могут быть вызваны каким -либо другим приложением. Однако, если вы добавите какие -либо фильтры намерения в объявление службы, он экспортируется по умолчанию. Лучше всего, если вы явно объявите android:exported атрибут, чтобы убедиться, что он ведет себя так, как вы намереваетесь. Услуги также могут быть защищены с помощью атрибута android:permission . Таким образом, другие приложения должны объявить соответствующий элемент <uses-permission> в своем собственном манифесте, чтобы иметь возможность запускаться, останавливаться или связываться с сервисом.

Примечание . Если ваше приложение нацелен на Android 5.0 (уровень API 21) или выше, используйте **JobScheduler** для выполнения фоновых служб.

Служба может защитить отдельные вызовы МПК, которые вносятся в него с разрешениями. Это делается путем вызова checkCallingPermission() до выполнения реализации вызова. Мы рекомендуем использовать декларативные разрешения в манифесте, поскольку они менее подвержены надзору.

ВНИМАНИЕ : не путайте разрешения клиента и сервера; Убедитесь, что вызываемое приложение имеет соответствующие разрешения, и убедитесь, что вы предоставляете те же разрешения для приложения Calling.

Интерфейсы связующего и мессенджера

Использование Binder или Messenger является предпочтительным механизмом для IPC в стиле RPC на Android. Они предоставляют четко определенные интерфейсы, которые обеспечивают взаимную аутентификацию конечных точек, если это необходимо.

Мы рекомендуем вам разрабатывать интерфейсы вашего приложения таким образом, чтобы не потребоваться проверки разрешений на интерфейс. Объекты Binder и Messenger не объявляются в рамках манифеста приложения, и поэтому вы не можете применить декларативные разрешения непосредственно к ним. Как правило, они наследуют разрешения, объявленные в приложении, манифестной для Service или Activity , в рамках которой они реализованы. Если вы создаете интерфейс, который требует аутентификации и/или элементов управления доступа, вы должны явно добавить эти элементы управления в качестве кода в интерфейсе Binder или Messenger .

Если вы предоставляете интерфейс, который требует элементов управления доступа, используйте checkCallingPermission() чтобы проверить, имеет ли вызывающий разрешение. Это особенно важно, прежде чем получить доступ к Сервису от имени вызывающего абонента, так как личность вашего приложения передается в другие интерфейсы. Если вы вызываете интерфейс, предоставленный Service , вызов bindService() может не удалиться, если у вас нет разрешения на доступ к данной службе. Если вам нужно разрешить внешний процесс взаимодействовать с вашим приложением, но у него нет необходимых разрешений для этого, вы можете использовать метод clearCallingIdentity() . Этот метод выполняет призыв к интерфейсу вашего приложения, как будто ваше приложение делало сам вызов, а не внешний вызывающий абонент. Вы можете восстановить разрешения вызывающего абонента позже с помощью метода restoreCallingIdentity() .

Для получения дополнительной информации о выполнении МПК с помощью службы см. Связанные службы .

Вещательные приемники

BroadcastReceiver обрабатывает асинхронные запросы, инициированные Intent .

По умолчанию приемники экспортируются и могут быть вызваны любым другим заявлением. Если ваш BroadcastReceiver предназначен для использования другими приложениями, вы можете применить разрешения на безопасность к приемникам, используя элемент <receiver> в манифесте приложения. Это предотвращает приложения без соответствующих разрешений отправлять намерение BroadcastReceiver .

Безопасность с динамически загруженным кодом

Мы решительно препятствуем загрузке кода извне вашего приложения APK. Это значительно увеличивает вероятность компромисса приложения из -за инъекции кода или фальсификации кода. Это также добавляет сложность вокруг управления версиями и тестирования приложений - и может сделать невозможным проверить поведение приложения, поэтому оно может быть запрещено в некоторых средах.

Если ваше приложение динамически загружает код, самое важное, что нужно помнить, это то, что динамически загруженный код работает с теми же разрешениями безопасности, что и приложение APK. Пользователь принимает решение установить ваше приложение на основе вашей личности, и пользователь ожидает, что вы предоставите любой код, который запускается в приложении, включая код, который загружается динамически.

Многие приложения пытаются загрузить код из небезопасных местоположений, таких как загрузка из сети, из-за незашифрованных протоколов или из во всем мире мест, таких как внешнее хранилище. Эти местоположения могут позволить кому -то в сети изменить контент в транзите или в другом приложении на устройстве пользователя, чтобы изменить контент на устройстве. С другой стороны, модули, включенные непосредственно в ваш APK, не могут быть изменены другими приложениями. Это верно, является ли код собственной библиотекой или классом, загружаемым с использованием DexClassLoader .

Безопасность в виртуальной машине

Dalvik - виртуальная машина времени выполнения Android (VM). Dalvik был построен специально для Android, но многие из проблем, касающихся безопасного кода в других виртуальных машинах, также применяются к Android. В целом, вам не нужно решать проблемы безопасности, связанные с виртуальной машиной. Ваше приложение работает в безопасной среде песочницы, поэтому другие процессы в системе не могут получить доступ к вашему коду или частным данным.

Если вы заинтересованы в том, чтобы узнать больше о безопасности виртуальных машин, ознакомьтесь с какой -то существующей литературой по этому вопросу. Два из наиболее популярных ресурсов:

Этот документ фокусируется на областях, специфичных для Android или отличается от других сред, среда виртуальной машины. Для разработчиков, испытываемых с программированием виртуальной машины в других средах, существуют две широкие проблемы, которые могут отличаться от написания приложений для Android:

  • Некоторые виртуальные машины, такие как время выполнения JVM или .NET, действуют как граница безопасности, изолируя код из базовых возможностей операционной системы. На Android VM Dalvik не является границей безопасности - песочница приложения реализована на уровне ОС, поэтому Dalvik может взаимодействовать с собственным кодом в том же приложении без каких -либо ограничений безопасности.
  • Учитывая ограниченное хранилище на мобильных устройствах, разработчики часто хотят создавать модульные приложения и использовать динамическую загрузку класса. При этом рассмотрите как источник, где вы получаете логику приложения, так и где вы храните ее на месте. Не используйте динамическую загрузку класса из источников, которые не проверены, такие как необеспеченные сетевые источники или внешнее хранилище, потому что этот код может быть изменен, чтобы включить вредоносное поведение.

Безопасность в собственном коде

В целом, мы рекомендуем использовать Android SDK для разработки приложений, а не использовать натуральный код с Android NDK . Приложения, построенные с нативным кодом, являются более сложными, менее портативными и с большей вероятностью включают общие ошибки коррупции памяти, такие как переполнение буфера.

Android строится с использованием ядра Linux, а знакомство с лучшими практиками безопасности Linux особенно полезно, если вы используете собственный код. Практика безопасности Linux выходит за рамки этого документа, но одним из самых популярных ресурсов является безопасное программирование Howto - создание безопасного программного обеспечения .

Важным отличием между Android и большинством средах Linux является песочница приложения. На Android все приложения работают в песочнице приложения, в том числе написанные на собственном коде. Хороший способ подумать об этом для разработчиков, знакомых с Linux, - это знать, что каждому приложению предоставляется уникальный идентификатор пользователя (UID) с очень ограниченными разрешениями. Это обсуждается более подробно в обзоре безопасности Android , и вы должны быть знакомы с разрешениями приложения, даже если вы используете собственный код.