Привет, Хабр! Я занимаюсь безопасностью мобильных приложений и с удовольствием слежу за развитием платформ Android и iOS, которые с каждым новым релизом становятся все привлекательнее для пользователей, «обрастают» новой интересной функциональностью и вместе с тем повышается их защищенность… или нет? Сегодня я хотел бы сделать небольшой обзор развития различных функций безопасности системы Android, как внутренних, направленных на усиление безопасности самой платформы, так и внешних, напрямую относящихся к приватности и данным пользователей. Статья не претендует на оригинальность, все материалы есть в свободном доступе, но они рассредоточены по множеству публикаций. Мне показалась интересной попытка собрать эту информацию и проследить, как эволюционировала безопасность Android от версии к версии, чему уделялось внимание в каждом релизе и как это повлияло на дальнейшее развитие. В статье я постараюсь дать ссылки на различные ресурсы, где можно подробнее почитать о терминах, технологиях и прочем. Хотелось бы всё это рассказать в текущей статье, но тогда она рискует никогда не выйти. Надеюсь, статья понравится и будет полезна всем, кто увлекается безопасностью мобильных приложений и операционных систем. Вступление Android 4.4 (KitKat, 2013 год) Android 5 (Lollipop, 2014 год) Android 6 (Marshmallow, 2015) Android 7 (Nougat, 2016) Android 8 (Oreo, 2017) Android 9 (Pie, 2018) Android 10 (Q, 2019) Android 11 (R, 2020) Android 12 (S, 2021) Заключение Ни одна статья про защищенность мобильных систем не обходится без сравнения iOS и Android. Я не стану исключением и время от времени, при описании различных элементов безопасности Android, буду давать отсылки на аналогичные методы iOS. В качестве вступления я хотел бы сфокусироваться на подходах к формированию модели безопасности этих систем на первоначальном этапе развития, а в заключении попытаться сравнить, как обстоят дела сегодня. iOS — закрытая операционная система без доступа к исходному коду и описанию того, что происходит внутри: один производитель «железа» и софта, невозможность «отката» и жесткие рамки поддерживаемых версий, сложная система проверки перед публикацией, надстройки над классической системой безопасности Unix. Android — система с открытым исходным кодом: различные производители железа, которые могут модифицировать код под себя, возможность разблокировки загрузчика и установки модифицированных сборок, достаточно простая проверка перед публикацией, использование большого числа механизмов безопасности Unix с минимальной их модификацией, множество предустановленных производителем приложений, которые могут делать что угодно.  Абсолютно разные подходы и модели, но с развитием систем некоторые механизмы безопасности начинают пересекаться и перетекают из iOS в Android и наоборот.  Что из этого лучше — каждый решает сам, но лично мне ближе подход Apple, поскольку они полностью контролируют происходящее с устройствами и софтом и могут диктовать более жесткие требования, с которыми разработчикам, если они и дальше хотят видеть свое программное обеспечение в магазине приложений, придется считаться. Что же происходит с безопасностью Android и как Google пытается обезопасить свою систему и пользователей, становится ли он все больше похож на iOS — посмотрим. Начнем с Android 4.4, которая еще поддерживается некоторыми разработчиками приложений и, вероятно, может считаться отправной точкой усиления контроля над данными пользователя и повышения уровня безопасности в целом. Проанализируем первые шаги Google на пути совершенствования безопасности Android. В этой версии впервые начали уделять внимание проблеме атаки «Человек посередине». Чтобы обезопасить пользователя, было предпринято несколько важных мер, которые в дальнейшем будут развиты и усилены (в Android 6 и выше): Предупреждение пользователя о добавлении нового доверенного сертификата. Раньше, как, впрочем, и сейчас, с сертификатами и пользовательским хранилищем можно делать почти все, что угодно, но теперь Android хотя бы предупреждает, что установленный сертификат может привести к нежелательным последствиям. Усложнение перехвата сетевого трафика, отправляемого и получаемого сервисами Google. Теперь система следит за тем, чтобы только сертификаты из белого списка могли подключаться к этим сервисам.  Несмотря на то, что мы начали с Android 4.4, не могу не упомянуть об интересном изменении, которое касается чтения системного журнала обычными приложениями. Начиная с Android 4.1, пользовательские приложения больше не имеют доступа к системному журналу, и не могут использовать разрешение «permission.READ_LOGS». Теперь это разрешение присутствует только у системных приложений и демона adb. По идее, это должно защитить пользовательские данные, если они вдруг попадают в системный лог. Хотя, кто знает, как системные приложения используют это разрешение (тем более, количество системных приложений от производителя к производителю может существенно отличаться). Система Android использует многие функции безопасности из мира Unix, т. к. в ее основе лежит ядро Linux. К примеру, каждое приложение в системе работает в собственной «песочнице» и не имеет доступа к данным других приложений, а также не может напрямую обращаться к другим процессам в системе. Это разделение реализовано на уровне ядра и представляет собой классическую работу с правами на директории и файлы в Linux. Во время установки приложения система присваивает ему уникальные User ID (UID) и Group ID (GID), таким образом каждому приложению соответствует свой пользователь. Кроме того, на уровне ядра уникальные UID и GID каждого приложения используются для разделения доступа к ресурсам системы (память и процессорное время). Таким образом, на этом же уровне для каждого приложения создается своя собственная  «песочница» (Application Sandbox). В первых версиях Android использовался исключительно механизм на основе прав пользователя, без применения дополнительных мер защиты, однако, начиная с версии 4.4, Android использует еще один механизм из мира Linux — систему принудительного контроля доступа SELinux. Теперь она работает в принудительном режиме, а не как раньше — в рекомендуемом. Это изменение преимущественно нацелено на защиту от эксплойтов для повышения привилегий и направлено только на важные и закрытые части системы, к которым у обычного пользователя не должно быть доступа. Дополнительно применены некоторые меры по усложнению атак на переполнения буфера. Для обычных пользователей это не заметно, зато может существенно помочь в борьбе с вредоносными приложениями, которые пытаются получить root-доступ или права администратора устройства. Google всегда осознавала проблему очень сильной фрагментации Android. Большое количество производителей, кастомные сборки, каждый модифицирует что-то под себя и, как правило, производители не спешат обновлять версии операционной системы из-за сложности адаптации новых версий под вносимые изменения. Такой подход сильно сказывается на защищенности устройств, которые долгое время работают без важных обновлений безопасности. Наглядной иллюстрацией описанной ситуации является диаграмма использования версий Android.  Проблема становится особенно хорошо заметна в сравнении с iOS. На диаграмме использования версий iOS ярко выражены «зубцы», по которым можно однозначно определить время выхода новой версии операционной системы. Немаловажно, что наиболее ранняя версия iOS, которая всё ещё используется, это 13.3 (2019 год). В то время, как на диаграмме Android до сих пор можно видеть версию 5.1 (2014 год). И изменение носит линейный характер, без явных «переломов» после выхода новой версии. Единственное отличие — это выход Android 9 и выше.  В Android 4.4 сделан первый шаг к решению этой проблемы — была существенно улучшена производительность системы на более слабых устройствах, чтобы старые телефоны могли беспрепятственно обновиться на новую версию без потери производительности. К сожалению, это не решило основную проблему обновления измененного производителем кода, но, вероятно, позволило выбрать правильный вектор движения.  Как мне кажется, выпуск пятой версии Android можно назвать «прорывом» в безопасности этой операционной системы. Хотя бы потому, что именно в этой версии был заложен правильный фундамент последующего развития безопасности системы (пусть не самый удачный, но все же). Android 5 продолжил дело своего предшественника (Android 4) и еще больше интегрировал SELinux в защитные механизмы системы. Теперь Enforcing mode (принудительный режим) обязателен не только для отдельных частей системы, но и для всего остального, включая пользовательские приложения. Таким образом, Android 5 можно назвать первой версией, которая полноценно использует возможности SELinux для разграничения доступа и контроля.  Предыдущие версии Android не использовали шифрование диска по умолчанию, такая опция была, но для её включения необходимо было основательно покопаться в настройках.  Но, начиная с пятой версии, Android использует шифрование диска по умолчанию с помощью классического способа Full-Disk Encryption.  Но не обошлось и без минусов: Данные, хранящиеся на SD-карте, всё еще никак не защищены и не зашифрованы.  Используется достаточно странный способ защиты ключа шифрования, знание которого позволяло получить все данные. Этот секретный ключ был зашифрован с использованием пароля, представляющем из себя строку «default_password» и его нельзя было изменить, если устройство не поддерживало режим Secure Startup. Этот режим позволял использовать произвольную фразу или цифровой код вместо пароля по умолчанию (чаще всего использовался код-пароль, установленный на устройстве). Но для включения Secure Startup необходимо было вручную выбрать этот способ загрузки. У Secure Starup есть один побочный эффект — ввод пароля осуществлялся на раннем этапе загрузки системы и без него телефон даже не принимал звонки.    По статистике, раньше далеко не все пользователи устанавливали код блокировки на свой телефон, аргументируя это тем, что неудобно каждый раз его вводить, чтобы воспользоваться устройством, например сделать фото и т. д.  На одном из семинаров по безопасности мой коллега проводил эксперимент, который наглядно показывал, насколько важен такой, казалось бы, незначительный, элемент, как PIN-код устройства. Эксперимент заключался в том, что необходимо было отдать свой телефон соседу на 5 минут. При этом у человека, завладевшего вашим устройством, не было ограничений — он мог делать с ним что захочет, смотреть фото, читать сообщения, почту и т. д. Было очень интересно наблюдать, как больше половины аудитории начинали возмущаться и просто отказывались участвовать в «самодеятельности».  Но после семинара многие всё-таки решили поставить пароль (просто на всякий случай).  Как раз чтобы сделать разблокировку более удобной, Google анонсировала функцию Smart Lock, которая позволяла разблокировать устройство с установленным паролем при помощи различных Bluetooth или NFC аксессуаров. Дополнительно можно было включить опции по разблокировке в определенных местах на основе данных GPS, а также запретить блокировать устройство, пока оно находится у вас в руках (на основе данных с акселерометра). Ну и вишенкой на торте стало использование биометрии, а именно, улучшение представленной в Android 4.0 функции распознавания лица (теперь ей хотя бы стало можно пользоваться).  Продолжая тему «передачи» устройства кому-либо, в Android 5 стал доступен гостевой режим. Передавая кому-то телефон, стало возможным быстро перевести его в режим гостя, в котором он выглядит, как после сброса до «заводских настроек». Честно говоря, для меня это было откровением — никогда в жизни не пользовался этой функциональностью и даже не знал, что она когда-то была. Несколько очень полезных и нужных функций при потере устройства появилось в пятой версии Android.  Первая из них — это возможность доступа к телефонной книге, фотографиям и сообщениям через аккаунт Google. То есть, данные теперь синхронизировались с облаком и достаточно было войти в свой аккаунт на новом телефоне, чтобы восстановить всю важную информацию с потерянного устройства.  Вторая очень важная функция — это возможность показать на карте местоположение телефона (или его последние координаты до того, как он был выключен), и главное — возможность удаленной очистки устройства.  И последнее, но немаловажное новшество — это защита от сброса до заводских настроек. При включении устройство не может быть подвержено Factory Reset без ввода аутентификационных данных аккаунта Google (если ваш телефон украли, его уже не получится продать — он будет требовать войти в систему). До 5-й версии для обновления Android необходимо было получить апдейт от производителя устройства. То есть, цепочка обновления выглядела достаточно сложно и непредсказуемо: сначала Google узнавала о проблеме и решала её, добавляла исправление в проект AOSP, производители устройств при очередном плановом обновлении (если оно вообще будет), забирали новый код из AOSP и компилировали его под себя, внося изменения, и только после этого он мог попасть к конечному пользователю (а мог и не попасть). Но с выходом 5-й версии был запущен процесс поставки обновлений для части компонентов операционной системы (а именно для WebView) через механизм обновления Google Play. Фактически это означало, что телефон будет своевременно получать все актуальные обновления так же, как обновляются приложения (конечно, не всегда это работает на благо). Удобно, просто и для закрытия критических уязвимостей не нужно ждать, когда производитель соизволит выпустить свой патч.  После выпуска 5-й версии компания Google продолжила добавлять новые механизмы безопасности, но также начала переосмысливать предыдущие подходы и допущенные ошибки. Это, наверное, первая версия Android, которая начинает заботиться о безопасности данных пользователей и доступе к этой информации для сторонних приложений. В последующих обновлениях мы увидим развитие этих механизмов. Прежде чем говорить об изменении логики работы, стоит объяснить, а что же представляют из себя эти Permissions (разрешения).  Операционная система Android устроена таким образом, что для выполнения некоторых операций или доступа к ресурсам, приложение должно иметь определенное разрешение. Эти разрешения разделяются на несколько уровней: Normal и Dangerous. Их отличие в том, что Dangerous-разрешения позволяют получать личную информацию пользователя или совершать потенциально опасные действия (например доступ к контактам или SMS-сообщениям). До Android 6 все было достаточно просто: пользователь во время установки приложения видел все разрешения, которые запрашивает приложение. Сначала шли все «опасные» разрешения, а после — все «нормальные». Имея всю информацию перед глазами, пользователь может понять, к чему будет иметь доступ приложение, и принять решение о его установке и использовании.  Начиная с Android 6, подход изменился: теперь при установке приложения нет экрана со списком всех разрешений. Приложение автоматически получает все необходимые Normal-разрешения, a Dangerous — необходимо запрашивать в процессе работы. Т. е. теперь разработчику недостаточно просто указать, что приложению нужен, например, доступ к контактам. Чтобы получить его необходимо явно вызвать диалог подтверждения. С одной стороны, это нововведение позволяет более атомарно и явно выдавать разрешения приложениям, разрешая только то, что необходимо. С другой стороны, потерялась наглядность и, чтобы посмотреть на всё, что доступно приложению, нужно зайти в настройки, выбрать конкретное приложение и только тогда просмотреть весь список. Но кто об этом знает и кто туда будет специально заходить и смотреть?  На мой взгляд, логичнее было бы предусмотреть какой-то промежуточный вариант, показать, какие разрешения выдаются приложению по умолчанию и какие оно может запросить в процессе работы. Но Google посчитала иначе — они просто убрали экран со списком всех разрешений при установке. Google и раньше «отбирала» некоторые права у приложений, ограничивая доступ к данным пользователя, например ограничение на чтение системного журнала, но, начиная с Android 6, это стало принимать более серьезный масштаб и с каждой новой версией «гайки будут закручиваться». В частности, в этой версии Android MAC адреса Wi-Fi и Bluetooth адаптеров нельзя получить без специального и явного разрешения пользователя. А сделано это, чтобы усложнить идентификацию устройства сторонними приложениями без ведома пользователя и сопоставление этих данных с данным Wi-Fi-точек, что часто используется для отслеживания устройства пользователя и его перемещения.  В действительности попытки повторить цепочку доверенной загрузки в iOS предпринимались еще в версии 4.4, но они были не очень успешны. Этот функционал не был полностью проработан и носил необязательный характер. Начиная с версии Android 6, функционал Verified Boot, который обеспечивает защиту от различных модификаций системного раздела и важных файлов системы при загрузке, начинает активно развиваться и становится все более сложным и подготовленным к полноценному использованию. В частности, в этой версии реализован ряд криптографических проверок целостности всех частей — от загрузчика до операционной системы. Однако пользователи все еще могут загрузить устройство, если проверка не была пройдена — при загрузке устройства возникает экран, который оповещает о модифицированном загрузчике.  Теперь не стоит волноваться, подключая телефон к зарядке на автобусной остановке или к другому непроверенному USB-порту, так как подключение устройств через USB теперь по умолчанию настроено на режим «только зарядка». Чтобы получить доступ к устройству и его содержимому, пользователь должен явно предоставить на это разрешение.  Удивительно, но полноценная и широко распространенная возможность использовать отпечаток пальца для разблокировки устройства появилась только в Android 6. Также, в этой версии была представлена возможность защиты ключей шифрования, которые создавались в приложении с использованием отпечатка, то есть доступ к ключу стало возможно получить только после прохождения пользователем процедуры биометрической идентификации.  И скорее всего это стало возможным благодаря реализации отдельного аппаратного уровня хранения информации, которую нельзя было получить даже при физическом доступе к устройству. Проще говоря — аппаратное хранение всей важной информации, включая отпечатки пальцев, пользовательские сертификаты, ключи, используемые для шифрования файловой системы, и многое другое.  Исторически сложилось, что в Android решение для создания резервных копий приложений было откровенно слабым. Было непонятно, что и как попадает в бекап, какие данные можно восстановить, а какие — нет. Теперь в Android 6 можно настроить автоматическое создание резервных копии как приложений, так и данных. Наконец-то, любые восстановленные приложения, будут такими же, как и раньше, и с ними можно продолжить работу с момента создания последней резервной копии. Но есть и минус — резервные копии в облаке по-прежнему не защищены пользовательским паролем, а значит, теоретически, их содержимое может быть доступно «большому брату» и это изменится только в Android 9.  С выходом Android 6, Google представила атрибут usesCleartextTraffic, как средство защиты от случайного использования протокола http. При правильно выставленном флаге приложению в процессе работы будет запрещено осуществлять взаимодействие по протоколу http с любыми серверами. Эта настройка является первым шагом Google на пути упрощения конфигурации сетевых взаимодействий для приложений.  До Android 6.0 оставалось только догадываться, получал ли телефон обновления безопасности и в каком состоянии он сейчас находится. Но в этой версии в раздел «О телефоне» была добавлена информация о том, какое обновление безопасности установлено на данный момент. Теоретически, это должно было заставить производителей устройств уделять более пристальное внимание доставке обновлений, а пользователям позволяло получить более полную информацию о безопасности своего телефона.  Но, как показало одно очень интересное исследование, в ходе которого на протяжении двух лет эксперты наблюдали за информацией об обновлениях безопасности и проверяли актуальное состояние устройств (действительно ли все патчи установились на устройство или что-то «потерялось в пути»). В итоге оказалось, что многие производители хитрят во время выпуска обновлений и, хотя они утверждают, что их устройства получили все актуальные патчи, на самом деле это не так. Некоторые исправления, по неизвестным причинам, «выпадают» из списков и вообще не доходят до пользователей. Но самое интересное, что иногда производители просто изменяют дату обновления, вообще не устанавливая никаких патчей на протяжении многих месяцев. Результаты этого исследования представлены в следующей таблице. После двух «рывков», которые принесли достаточно много нововведений, и пересмотра некоторых существующих механизмов разработчики Android решили немного «отдохнуть» от безопасности и переключить свое внимание на другие аспекты платформы. Но несколько вещей они всё-таки доработали. Развивая концепцию доверенной загрузки, которую существенно улучшили в Android 6, начиная с 7-й версии, скомпрометированные устройства больше не запускаются. Также добавлена поддержка исправления ошибок, которые могли возникнуть при загрузке устройства (это всё-таки больше направлено на повышение стабильности работы системы, чем на защиту от злоумышленников, но теперь тоже входит в реализацию цепочки доверенной загрузки в исполнении Google).  Как мы помним, в Android 5 впервые было по умолчанию включено шифрование диска (а на самом деле, внутренней памяти устройства), но оно имело несколько существенных недостатков. Теперь же, начиная с Android 7, появилась опция пофайлового шифрования данных (вместо используемого ранее Full-Disk Encryption). Этот тип шифрования намного более удобен для пользователя и представляет собой некоторое сочетание FDE и Secure Startup, демонстрирующее все положительные стороны каждого из способов.  Большинство пользовательских данных зашифрованы с использованием производной от ключа-пароля, установленного на устройстве, а исполняемые файлы приложений и системные утилиты, необходимые для работы устройства, до первой разблокировки зашифрованы при помощи аппаратных ключей и доступны сразу после загрузки устройства.  Но опять не обошлось без минусов, хотя и не таких существенных — пользователь не мог сам выбрать, какой именно режим шифрования будет использоваться в его устройстве, это закладывалось изначально производителем телефона. И если крупные игроки понимали необходимость перехода на новый способ, то небольшие компании продолжали использовать менее безопасный.  Есть способ проверить, какое именно шифрование использует ваше устройство, достаточно включить в настройках для разработчика опцию USB Debugging, подключить телефон к компьютеру и выполнить команду adb:  adb shell getprop ro.crypto.type  Если команда вернула слово «file», то смартфон использует шифрование FBE.  Наверное, основным и самым полезным новшеством стали настройки безопасного сетевого соединения. Сертификаты, которые добавляет пользователь, теперь по умолчанию считаются недоверенными и не могут использоваться для организации защищенного соединения. Другими словами, даже если пользователь установил сертификат злоумышленника на свое устройство, это не дает возможность осуществить атаку «Человек посередине».  Вторым очень важным изменением является возможность настройки безопасности сетевого взаимодействия, которое позволяет более четко определять параметры соединений. Теперь конфигурация сетевого взаимодействия — это XML-файл, в котором настраиваются параметры  безопасности. Ключевые возможности, которые предоставляет такой подход: Custom trust anchors — настройка доверия центрам сертификации (CA), которым будет доверять приложение при сетевом взаимодействии. Например, доверие определенным самоподписанным сертификатам или ограничение набора общедоступных центров сертификации, которым доверяет приложение (добавленные пользователем в доверенные или те CA, которым доверяет система). Debug-only overrides — настройка соединений специально для Debug-версии приложения, что позволяет разграничивать среды разработки и Production. Cleartext traffic — более детальная настройка разрешения или запрета соединений по http для всего приложения или конкретных доменов. Certificate pinning — настройка для реализации SSL Pinning, то есть теперь не нужно самому переживать за проверку отпечатка сертификата сервера, достаточно просто указать его значение в конфиге и система возьмет на себя все остальные рутинные операции.  После небольшого перерыва в виде Android 7, Google решила сделать Android 8 одним из самых важных обновлений системы после пятой версии. Новая модульная система позволяет обновлять компоненты ОС независимо, появилась система ограничений фоновой работы приложений и многое-многое другое. Очень хорошо информация об обновлении описана в статье Евгения Зобнина, так что здесь я приведу лишь некоторые, наиболее важные на мой взгляд вещи.  Наверное, одним из самых значимых изменений стала переработка внутренних компонентов Android, которая началась уже давно, после отделения WebView и других системных вещей в отдельные компоненты, которые можно обновлять независимо, но такого масштабного изменения не было никогда. TREBLE — это способ разделения Android на две независимые части, которые обеспечивают связь с «железом» (ядро Linux) и операционной системой Android, а также призваны решить проблемы фрагментации Android и доставки патчей на устройства различных производителей.  Другими словами, Google больше не зависит от производителей устройств в части обновлений безопасности для внутренних компонентов Android. Теперь Google сама решает, как и когда будет обновлен ваш телефон и какие обновления безопасности необходимо установить. Такой подход даже удобнее, чем установка обновлений в iOS, где патчи безопасности приходят вместе с обновлениями системы и не могут устанавливаться отдельно. В Android 6 впервые начали «отбирать» у приложений доступ к аппаратным идентификаторам устройства, в Android 8 этот процесс продолжили. Теперь приложениям запрещено получение информации об Android ID — уникальном идентификаторе, который генерируется при первой загрузке устройства (теперь для каждого приложения он будет уникальным). Также серийный номер телефона нельзя получить без специального и явного разрешения пользователя. В запрещенные идентификаторы также попали время последней загрузки и MAC-адрес Bluetooth.  В Android 8 наконец-то изолировали WebView, теперь он выполняется в отдельном процессе, и это очень здорово. Это означает, что при наличии уязвимостей в этом компоненте больше не удастся получить доступ к процессу приложения, так как изоляция реализована с достаточно жесткими условиями, рендеринг страницы запускается в ограниченной «песочнице» без доступа к ресурсам системы и интернету, то есть просто отображает контент страницы, который ей передали.  Когда наш телефон сканирует эфир на наличие точек доступа, вместе с различными параметрами он отправляет и свой MAC-адрес. Если собрать информацию с нескольких точек доступа, можно определить, где и в какое время находилось устройство с определенным MAC. И наконец, в Android 8 добавили функцию рандомизации Mac-адреса при поиске сетей (если я не ошибаюсь, в iOS это было реализовано в 8-й версии в 2014 году). Это первый шаг на пути обеспечения приватности пользователя — он не позволяет отследить реальный MAC-адрес и сопоставить его конкретным устройством.  По сравнению с предыдущим выпуском Android 9 несет изменения, в большей степени направленные именно на конфиденциальность пользователя. В прошлой версии Android MAC-адреса менялись только при сканировании точек, доступных для подключения. Логическим продолжением стало использование случайного адреса при подключении к сети.  То есть, при подключении к различным точкам доступа им будут соответствовать разные MAC-адреса, что затруднит идентификацию устройства. Чтобы помнить, какой точке доступа какие MAC-адреса соответствуют, в Android есть специальная табличка сопоставление адреса и Wi-Fi сети. Но по традиции, эту опцию добавили только в режим разработчика, где её нужно самому найти и включить.  Начиная с Android 6, постепенно вводился новый функционал, позволяющий упростить конфигурацию сетевого взаимодействия и подготавливающий разработчиков к полному запрету на http соединения. И вот, наконец, в Android 9 по умолчанию для приложений стоит запрет на использование протокола http! Конечно, никто не запрещает принудительно его включить для всего или для определенных доменов, но если это не сделано, то приложение просто не сможет общаться с сервером по небезопасному протоколу. Частный DNS (реализация DNS over TLS) шифрует весь DNS-трафик, предотвращая прослушивание или изменение его третьей стороной. Эта функция добавляет недостающий уровень безопасности и конфиденциальности всем DNS-запросам, которые отправляет устройство. По умолчанию Android автоматически использует DNS over TLS, если функциональность поддерживается DNS-сервером. Но, конечно, это так же вынесено в настройки и может быть отключено.  Прошло очень много времени с добавления облачных резервных копий (Android 6, 2015 год), прежде чем Google всё-таки реализовала их шифрование на основе пользовательского пароля и теперь «большой брат», в теории, не сможет получить к ним доступ. Эта функциональность автоматически включается при соблюдении следующих условий: Пользователь включил резервное копирование на Android 9 или выше. Пользователь установил блокировку экрана своего устройства, используя PIN-код, графический ключ или пароль. Для восстановления данных из зашифрованных резервных копий, требуется ввод PIN-кода устройства, графического ключа или пароля.  До Android 9 можно было дать доступ к файлу внутри своей «песочницы», установив ему флаг WORLD_READABLE или WORLD_WRITABLE (фактически, это аналогично выполнению команды chmod c определенными параметрами). Это было достаточно плохой практикой с непредсказуемыми последствиями. Начиная с девятой версии Android, использование такого подхода запрещено (дополнительно контролируется правилами SELinux), а для предоставления доступа к данным своего приложения необходимо использовать только механизмы IPC (межпроцессного взаимодействия), в виде Content Providers, которые более безопасны, подконтрольны разработчикам и регулируются внутренними механизмами безопасности.  Об одном из самых заметных security-новшеств Android 9 стало известно еще до выхода бета-версии. Это, конечно же, запрет на использование камеры, микрофона и любых сенсоров приложениями, которые находятся в состоянии Idle, то есть свернуты и работают в фоне. Таким образом разного рода зловредные приложения, которые любили снимать и слушать происходящее вокруг, теперь должны искать новые способы это делать. Но есть один нюанс: как быть с софтом, предназначенным для поиска смартфона? Есть множество приложений, позволяющих удаленно снимать и прослушивать происходящее, чтобы быстрее найти свой украденный смартфон или передавать координаты устройства для поиска. Для этого Google в очередной раз предлагает использовать так называемый foreground service. Это специальный тип фоновой службы, которая при использовании сенсоров показывает значок и уведомление в панели уведомлений, а потому заметна пользователю (в теории).  В Android есть ряд приватных, недоступных обычным приложениям API. К ним, конечно, можно попробовать получить доступ с помощью рефлексии. Так иногда поступают разработчики приложений, что может приводить к уязвимостям и нестабильной работе приложений (скрытые API могут меняться и исчезать от версии к версии). В Android 9 доступ к приватным API запрещен. Более того, новая версия Android выводит уведомление в том случае, если приложение использует объявленные устаревшими (deprecated) API. Это должно заставить разработчиков перейти на использование новых API.   Эта система продолжает дело 9-й версии, постепенно «закручивая гайки» по идентификации устройства и доступа к различной информации пользователя. Складывается ощущение, что Google решила вплотную приблизиться к iOS и постепенно сократить допустимый объем собираемой сторонними приложениями информации до минимума, оставляя, между тем, такую возможность своим приложениям.  Что интересно, начиная с этой версии Google перестаёт давать названия версиям операционной системы, связанных со сладостями. Очень жаль, что это осталось в прошлом.  Очевидно, что добавленный в Android 9 механизм рандомизации MAC-адреса при подключении хорошо себя зарекомендовал, так что в новой 10-й версии больше не нужно руками включать эту опцию — теперь она включена по умолчанию.  Если раньше можно было спокойно запускать Activity в фоне и, например, пытаться собирать какую-то информацию (к примеру, реализовать атаку Task Hijacking), то начиная с 10-й версии это запрещено. Остается только один вариант: предупредить пользователя и только после этого запускать фоновые Activity.  Еще несколько идентификаторов (Serial Number, IMEI, DeviceId, MEID, SIM Serial Number, Subscruber ID) перешли в разряд запрещенных к получению обычными приложениями. С одной стороны, это существенно усложняет жизнь различным приложениям, которые следят за пользователем и идентифицируют устройство. Но, с другой стороны, легитимным приложениям становится намного сложнее определить уникальность устройства и «привязаться» к нему.  Тем не менее, встроенные приложения от производителя и компании Google по-прежнему имеют доступ к этой информации.  Практически каждый год появляется очередная новость о серьезной уязвимости Android, позволяющей приложениям мониторить буфер обмена и копировать оттуда данные (несмотря на то, что это вполне легитимная функциональность буфера обмена). В какой-то мере это обоснованное опасение, хотя бы потому, что был обнаружен троян, основанный как раз на этой особенности. Троян не собирал все, что находится в буфере обмена, а ждал, когда в него попадет адрес криптокошелька и подменял его адресом, принадлежащий злоумышленникам. Программа поддерживала следующие криптовалюты: Bitcoin, Litecoin, Monero и Ethereum.  Теперь, начиная с 10-й версии, доступ к буферу обмена разрешен, только если приложение активно и находится в foreground (на переднем плане).  Чтобы защитить содержимое экрана, доступ к нему в Android 10 существенно ограничен, для чего изменены соответствующие разрешения (READ_FRAME_BUFFER, CAPTURE_VIDEO_OUTPUT и CAPTURE_SECURE_VIDEO_OUTPUT).  Начиная с Android 10, эти разрешения доступны только системным приложениям. Система следит за использованием разрешений при помощи signature-access. То есть, использовать разрешение может только приложение, которое подписано тем же сертификатом, что и «владелец» разрешения (то приложение, которое его регистрирует в системе). А начиная с Android 10, это приложение — system, то есть сама система Android. На данный момент это один из самых действенных способов перенести различные разрешения в формат «системных», просто ограничив к ним доступ по цифровой подписи приложения. Приложения, которым требуется доступ к содержимому экрана устройства, должны использовать специальный MediaProjection API, который всегда предупреждает пользователя о намерении приложения получить доступ к экрану и запрашивает его явное согласие.  Google продолжает политику изменения разрешений, добавляет новый функционал и работает над их гранулярностью. Хотя механизм по-прежнему оставляет желать лучшего и трудно понять, что именно скрывается за той или иной группой разрешений, особенно учитывая, что они постоянно их меняют.  Появился совершенно новый интересный механизм одноразовых разрешений, которые дают доступ только на то время, пока приложения не будет закрыто, и в следующий раз пользователю снова нужно будет выдать это разрешение. Этот функционал пока работает только для доступа к локации, микрофону и камере, но думаю, что в будущем этот список будет расширен. Эта функция подозрительно похожа на аналогичный функционал в iOS 13 (2019 год). Android 11 представляет функцию, которая позволяет заблокировать запрос разрешений, если пользователь дважды отменил запрос. После двойного отказа в разрешении пользователям придется вручную предоставить их в настройках. Интересное решение, позволяющее не показывать пользователю запрос каждые 30 секунд, пока он не согласится.  Теперь, когда приложение запрашивает разрешение на доступ к местоположению, Android 11 сначала выдает такое разрешение только для запущенного приложения, а если геолокация необходима и в фоновом режиме, формируется отдельный запрос. Этот второй запрос требует от пользователей дополнительных действий вместо того, чтобы просто нажимать «Oк…, Oк…, разрешить…». Чтобы включить фоновый доступ к местоположению, пользователи должны на странице разрешений приложения выбрать для определения местоположения параметр «Разрешить все время». Помимо этого, Google также требует, чтобы разработчики приложений объясняли, почему их приложению в первую очередь нужен фоновый доступ к местоположению.  Если вы установили приложение, предоставили ему разрешения, но не используете его в течение нескольких месяцев (точные временные рамки «нескольких месяцев» так и не определены), разрешения будут отозваны и могут быть повторно включены только вручную. Эта функция работает от приложения к приложению и не включена по умолчанию (но очень вероятно, что в следующем релизе Google включит ее для всего, как это уже не раз бывало). Продолжая развивать механизм Treble, существенно улучшенный в Android 8, система теперь получает все критические обновления напрямую из Google Play. Это очень сильно упрощает процесс и повышает общий уровень безопасности устройств, так как теперь обновления системы могут устанавливаться автоматически. Но что же делать пользователям, у которых нет магазина приложений Google и их сервисов, пока не очень понятно. Вероятно, надеяться на производителя своего смартфона.  Наверное, один из самых интересных релизов за последние годы, очень насыщенный различными функциями приватности и безопасности. Даже на конференции Google отдельно упоминала, что теперь приватность является одной из основных составляющих системы. Ну что же, посмотрим, насколько это будет соответствовать действительности. Кстати, есть потрясающий разбор всех нововведений Android 12 (откуда я и взял информацию, так как это наиболее подробный и качественный обзор) от автора канала Android Guards, советую его посмотреть, если кто хочет подробностей. Все новшества я описывать не стану, остановлюсь на тех, которые мне показались наиболее интересными. Теперь, по аналогии с iOS, при использовании камеры и микрофона в правом верхнем углу будет отображаться отдельный индикатор, который уведомит пользователя, что какое-то приложение задействует указанные устройства. Это не просто индикатор, а полноценная область, откуда можно сразу же «отнять» разрешения.  Другой не менее интересной особенностью стало наличие в системе «переключателя», который отключает использование микрофона и камеры для всех приложений. Интересное решение, которое показывает, какие приложения запрашивали доступ к камере, микрофону и геолокации за последние 24 часа. И также как из окна с индикацией об активности камеры и микрофона эти разрешения можно будет сразу «отобрать». На самом деле это очень правильный ход со стороны Google — они позволяют управлять важными разрешениями и доступами интуитивно понятно для пользователя. Больше не нужно «ходить в настройки», искать там приложение, разбираться в куче меню, а достаточно нажать пару кнопок и приложение больше не сможет использовать те части системы, которые вы не хотите. Пока в данный дашборд включены только камера, микрофон и геолокация, но я думаю, что в следующих релизах данная функциональность будет расширена.  Как мы помним, начиная с 6-й версии Android, началось жесткое ограничение доступа приложений к различным идентификаторам, в том числе к MAC-адресам Wi-Fi и Bluetooth, впоследствии досталось и разрешениям на сканирование сети и доступ к устройствам поблизости. Чтобы приложения Bluetooth корректно работали, необходимо было запрашивать доступ к геолокации (хотя причем тут местоположение и Bluetooth вообще непонятно). Получившему такое разрешение приложению становилось доступно намного больше возможностей, чем действительно необходимо. И кто знает, как оно ими пользовалось?  Теперь же, в Android 12, ввели отдельное специальное разрешение именно для Bluetooth и всего, что с ним связано. Возможно, на это повлияла популярная сегодня тема умного дома и большое количество датчиков, использующих BLE. Но главное, если появилось отдельное разрешение на эту технологию, может Google и дальше продолжит более логично их разделять, что было бы отлично, так как сейчас, лично для меня, некоторые разрешения совершенно не отражают всех возможностей, которые за ними стоят. В 10-й версии Android уже поработали над буфером обмена и запретили его использование в фоновом режиме. В новой версии Android механизм работы с данными из буфера обмена также усовершенствован. Теперь, когда приложение пытается получить данные из буфера обмена, пользователю будет выведено уведомление (toast сообщение), информирующее, что приложение «залезло» в скопированные данные. Этот механизм практически аналогичен функционалу, который появился в iOS 14 (2020 год).  И это очень правильное изменение, которое добавит больше ясности и прозрачности в работе приложений.  В прошлых версиях уже добавляли такое понятие, как приблизительная геолокация, но в Android 12  это «выставлено напоказ». При запросе приложения на геолокацию пользователь может сразу выбрать в красивом диалоге, выдавать ему точное местоположение или приблизительное (хотя до сих пор непонятно, насколько она действительно «приблизительное»). Наконец-то, спустя столько времени, страданий и проблем, Google услышала молитвы безопасников и объявила атрибут exported обязательным к заполнению для всех компонентов приложения. Тут стоит немного прояснить: в Android-приложении присутствуют так называемые экспортируемые компоненты, которые могут быть вызваны другими приложениями. Чтобы сделать компонент экспортируемым, достаточно указать ему атрибут exported=true, но многие забывают, что это не единственный способ. К примеру, при указании любых intent-фильтров, компонент автоматически становится экспортируемым. И это не редко приводило к проблемам безопасности, когда внутренние элементы приложения оказывались доступны для других приложений. И теперь, наконец, этот атрибут стал обязательным для заполнения и это привнесет намного больше ясности и понимания, что именно будет доступно другим приложениям. Конечно, в данной статье не удалось охватить все аспекты безопасности, которые добавлялись в каждой версии, но основные вещи я постарался осветить.  Если проследить эволюцию различных систем безопасности Android, можно заменить определенную последовательность. Сначала Google старалась уделять намного больше внимания внутренним механизмам безопасности, разграничению доступа, контролю приложений и противодействую различным атакам на саму систему. После достижения определенного уровня зрелости этих механизмов основные силы были направлены на обеспечение приватности пользователя и защиту его данных. И что интересно, Google нередко вводила различные механизмы, которые сначала оставались выключенными по умолчанию, чтобы определить, насколько они хорошо работают, собрать статистику и в следующем релизе выпустить их доработанными, готовыми к массовому использованию и включенными по умолчанию.  В плане механизмов безопасности система Android все больше и больше начинает походить на iOS. Конечно, до полного тоталитаризма еще далековато, но предпосылки и сходство определенно есть. Как мы видим, некоторые из механизмов приватности впервые появлялись в iOS и постепенно переходили в Android (рандомизация Mac-адресов, запрет на доступ к идентификаторам устройства, одноразовые разрешения и т. д.). Это разумно: брать интересные и работающие решения и применять их для обеспечения безопасности и приватности пользователей. На мой взгляд, Google проделала очень большую работу по обеспечению безопасности своей платформы и продолжает развивать эту сторону своей операционной системы.  Надеюсь, в ближайшее время мы увидим еще больше интересного функционала и защитных мер, которые сделают Android самой защищенной системой.  Ну а пока, если вам интересно узнавать о новостях из мира мобильной безопасности, читать различные технические статьи и получать информацию о новых методиках анализа приложений, приглашаю вас в мой телеграм-канал, посвященный всем этим темам: Mobile AppSec World. До встречи! Архитектор по информационной безопасности