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

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

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

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

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

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

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

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

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

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

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

API Play Integrity помогает вам проверить, что взаимодействия и запросы к серверу исходят от вашего подлинного двоичного файла приложения, работающего на подлинном устройстве 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, использование защищенных сетей настоятельно рекомендуется для всех приложений, которые взаимодействуют по сети.

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

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

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

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

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

Проверка входных данных

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

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

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

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

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

Данные пользователя

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

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

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

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

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

Будьте осторожны при записи в журналы на устройстве. На Android журналы являются общим ресурсом и доступны приложению с разрешением READ_LOGS . Несмотря на то, что данные журнала телефона являются временными и стираются при перезагрузке, ненадлежащее ведение журнала пользовательской информации может непреднамеренно привести к утечке данных пользователя в другие приложения. Помимо отказа от регистрации PII, ограничьте использование журнала в производственных приложениях. Чтобы легко реализовать это, используйте флаги отладки и настраиваемые классы 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 более безопасными.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Исключение из контроля источника

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

Ключи, специфичные для окружающей среды

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

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

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

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

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

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 порядке.

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

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

  • Используйте 256-битный AES для коммерческих целей. (Если недоступно, используйте 128-битный AES.)
  • Для криптографии на основе эллиптических кривых (EC) используйте открытый ключ длиной 224 или 256 бит.
  • Знайте, когда следует использовать режимы блоков 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 с Service и BroadcastReceiver . Механизмы Android IPC позволяют вам проверить подлинность приложения, подключающегося к вашему IPC, и задать политику безопасности для каждого механизма IPC.

Многие элементы безопасности являются общими для механизмов IPC. Если ваш механизм IPC не предназначен для использования другими приложениями, установите атрибут android:exported на false в элементе manifest компонента, например, для элемента <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 , и вы должны быть знакомы с разрешениями приложения, даже если вы используете собственный код.