В Google Play приложений, которые будут тебе показывать рекламу, больше 40%. Так что если у тебя смартфон на Android и ты пользуешься мобильными приложениями, то, скорее всего, ты понимаешь, о чем речь, рассказывает эксперт Кибербезопасности. Используя такие приложения, ты запускаешь встроенный в них AdSDK, который подгружает со своего сервера рекламные объявления. И чаще всего это объявления MRAID, которые через javascript обращаются к нативным функциям твоего смартфона: например, при помощи mraid.storePicture() кешируют картинки во внешнем хранилище. Звучит небезопасно, правда?
Бизнес-логика AdSDK часто непрозрачна для разработчика, который встраивает его в свое мобильное приложение. Программный код AdSDK работает с теми же привилегиями, что и приложение-носитель. Если носителю какие-то специальные разрешения не нужны, но они нужны AdSDK — носителю придется запросить их. Любой уважающий себя AdSDK затребует от тебя доступ к ID смартфона и геолокации, чтобы показывать тебе релевантные объявления.
AdSDK-провайдеры вынуждены мириться с небезопасностью по многим причинам. Несколько самых очевидных:
- между рекламодателем и твоим смартфоном может быть непредсказуемое число промежуточных звеньев;
- объявления для показа выбираются динамически;
- на сегодняшний день не существует инструментов для гарантированной дезинфекции JS-кода.
Поэтому AdSDK-провайдеры рассматривают каждое объявление как потенциально злонамеренное и используют механизм защиты, который запрещает программному коду объявлений читать чужие файлы из внешнего хранилища твоего смартфона. Этот запрет реализуется в два шага.
1. AdSDK помещает программный код каждого объявления в изолированный экземпляр встроенного браузера WebView и ограничивает набор разрешений, которыми этот экземпляр может пользоваться.
2. Доступ программного кода объявления к внешнему миру, в частности к локальным файлам внешнего хранилища твоего смартфона, регламентируется в соответствии с концепцией SOP — чтобы программный код объявления не мог читать из внешнего хранилища чужие файлы.
Импровизированный оракул
При этом программному коду объявления разрешается пользоваться «импровизированным оракулом»: обращаться к внешнему хранилищу с, казалось бы, безобидным вопросом: «А существует ли у тебя файл X?»
Но даже наличие определенных файлов может рассказать, какие лекарства ты принимаешь, какой у тебя круг общения и что ты за человек.
Возможность создания такого оракула с технической точки зрения не нарушает SOP, согласно четвертому разделу RFC6454. Дело в том, что этот оракул злоупотребляет тонким, но фундаментальным различием между моделями безопасности, реализованными в обычных веб-приложениях и в мобильных приложениях.
Тонкое различие в моделях безопасности веб-приложений и мобильных приложений
В обычных веб-приложениях доступ к кросс-доменным ресурсам координируется через CORS-запросы — совместными усилиями пользовательского веб-браузера и удаленного веб-сервера. Фактически немногие современные веб-сайты смогли бы работать, если бы SOP напрочь запретил возможность использования кросс-доменных ресурсов. Эта ключевая особенность веб-программирования выглядит довольно-таки безобидной, по крайней мере в своем первоначальном веб-контексте. Но она имеет интересные последствия для конфиденциальности, когда используется в мобильном контексте. В случае с внешним хранилищем твоего смартфона, где файлы тоже, по идее, принадлежат разным доменам, координацию доступа осуществлять некому.
Встраиваемые браузерные компоненты, такие как WebView, позволяют мобильному приложению инклудить локальные файлы из внешнего хранилища твоего смартфона. Когда AdSDK использует для загрузки объявления loadDataWithBaseURL(), то коду HTML этого объявления разрешается инклудить локальные файлы из внешнего хранилища твоего смартфона в качестве DOM-элементов. Пробуя подключить DOM-элемент, чей URI указывает на локальный файл, мобильное объявление тем самым узнаёт, существует ли этот файл на твоем смартфоне.
Такой импровизированный оракул работает, если:
- ты используешь относительно старую версию Android (до версии 5.0);
- AdSDK взаимодействует со своим сервером через HTTP вместо HTTPS.
Печальная новость заключается в том, что три из четырех самых распространенных AdSDK — AdMob, MoPub и AdMarvel — передают свои объявления именно через HTTP.
Примеры угроз
Теперь я хочу на реальных примерах показать, как знание о наличии некоего файла может быть использовано для эксфильтрации твоей конфиденциальной информации.
GoodRx
GoodRx — приложение для поиска лекарств. Оно кеширует изображения лекарств, которые пользователь искал или добавил в закладки. Злоумышленник может создать список из нескольких десятков антидепрессантов и подготовить массив, который будет содержать имена соответствующих изображений, чтобы затем сравнивать их с уже кешированными изображениями. Таким образом информация о любых препаратах, которые ты принимаешь, может оказаться в руках людей, которым ты бы предпочел никогда ее не доверять.
Dolphin
Dolphin — веб-браузер для Android. Приложение кеширует во внешнем хранилище изображения и загруженные страницы, чтобы уменьшить нагрузку на сеть. В качестве имен файлов для кешированных адресов Dolphin использует хеши, сгенерированные функцией String.hashCode(). Это 32-битное целочисленное значение. Уже описанным способом — проверяя наличие файлов с определенных сайтов — можно выяснить, посещал ли ты их.
Внимательный читатель заметит, что здесь через параметр src элементу scriptпередается не файл JS. Но скрипт загружать и не нужно, достаточно проверить наличие целевого файла. Если целевой файл присутствует на твоем смартфоне, то WebView радостно вызывает callback, который генерирует событие «Загрузка прошла успешно». Эта техника позволяет правильно определять сайты, которые ты посещал через Dolphin.
KakaoTalk
KakaoTalk — еще одно приложение, которое может стать брешью в твоей безопасности. А возможно, не только твоей. Миниатюрные аватарки твоих друзей приложение кеширует во внешнем хранилище. Если злоумышленник сгенерирует таблицу сопоставления кешированных миниатюр с соответствующими им людьми, то сможет легко идентифицировать твоих друзей. Даже если число попыток будет ограничено, все равно возможно узнать, было ли показано объявление конкретному человеку.
Как? А все тем же сканированием во внешнем хранилище. Только теперь злоумышленник будет искать среди кешированных аватаров твоих друзей. При этом следует понимать, что даже частичная информация о социальных пересечениях жертвы помогает однозначно идентифицировать ее. Предполагаемая личность может быть затем подтверждена при помощи данных геолокации и других метаданных, доступных злонамеренному рекламодателю. Метаданных, которые по отдельности не значат практически ничего, но в совокупности — достоверно идентифицируют личность.
Итоги
Когда речь заходит о кибербезопасности — по крайней мере, когда речь о ней заходит в корпоративном ключе, — принято говорить об управлении рисками. Следует понимать, что при желании нас могут взломать: вопрос только в том, сколько это будет стоить злоумышленнику и как сильно он хочет взломать.
Для атаки, которую я описал, насколько мне известно, пока нет противоядия. Но осведомлен — значит вооружен. Поэтому, когда будешь скачивать очередное бесплатное приложение с рекламными объявлениями, помни, что заплатишь ты не только тем, что посмотришь на товары, но, возможно, и конфиденциальностью.