Утечка Конфиденциальных Данных При Кэшировании Сетевых Запросов На Платформе Ios

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

Например, критической уязвимостью является потеря конфиденциальности в приложениях, манипулирующих номерами банковских карт и кодами аутентификации CVV2/CVC2. Одной из частых ошибок при разработке защищенных приложений для мобильной платформы iOS, приводящей к частичной или полной потере конфиденциальности передаваемых данных, является чрезмерное кэширование межсетевых запросов.

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

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

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

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

В контексте мобильных приложений неправильное использование кэша HTTP-запросов приводит к снижению производительности приложения и частичной или полной потере конфиденциальности.

Примером распространенной ошибки, которая может привести к снижению производительности, является многократное кэширование запросов приложением (двойное кэширование).



Испытание боем

Давайте рассмотрим пример неправильного использования кэша межсетевых запросов.

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

Межсетевые запросы хранятся в локальной базе данных SQLite в домашнем каталоге приложения по относительному адресу Library/Caches/.

/Кэш.

дб.

Схема базы данных приведена ниже.

Схема базы данных

  
  
  
  
   

CREATE TABLE cfurl_cache_schema_version(schema_version INTEGER); CREATE TABLE cfurl_cache_response(entry_ID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, version INTEGER, hash_value INTEGER, storage_policy INTEGER, request_key TEXT UNIQUE, time_stamp NOT NULL DEFAULT CURRENT_TIMESTAMP); CREATE TABLE cfurl_cache_blob_data(entry_ID INTEGER PRIMARY KEY, response_object BLOB, request_object BLOB, proto_props BLOB, user_info BLOB); CREATE TABLE cfurl_cache_receiver_data(entry_ID INTEGER PRIMARY KEY, receiver_data BLOB); CREATE INDEX request_key_index ON cfurl_cache_response(request_key); CREATE INDEX time_stamp_index ON cfurl_cache_response(time_stamp); CREATE INDEX proto_props_index ON cfurl_cache_blob_data(entry_ID); CREATE INDEX receiver_data_index ON cfurl_cache_receiver_data(entry_ID);

Столбец request_key в таблице cfurl_cache_response базы данных хранит универсальный идентификатор ресурса (URI), к которому обращается приложение, включая запросы HTTPS. Такие запросы могут включать конфиденциальные данные пользователя, включая данные аутентификации пользователя.

Например, приложение B использует квази-RESTful интерфейс для взаимодействия с веб-службой и отправляет запрос GET для авторизации пользователя.



sqlite> select request_key from cfurl_cache_response; .

https://example.com/api/1.0/authЭlogin=Selma_Nagel&password=qwerty .



Столбец получателя_данных в таблице базы данных cfurl_cache_receiver_data хранит ответы сервера, полученные приложением, включая запросы HTTPS. Таким образом, в Приложении Б используется веб-форма для оплаты услуг с помощью банковской карты.



sqlite> select receiver_data from cfurl_cache_receiver_data; .

<input data-val="true" .

="" id="CardNumber" name="CardNumber" type="hidden" value="1231 1231 1231 1234"> <input data-val="true" .

="" id="CardCode" name="CardCode" type="hidden" value="321"> .



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

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

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



Как это стало возможным?

Объект класса NSURLCache, доступный через метод +sharedURLCache, отвечает за кэширование межсетевых запросов внутри мобильного приложения, выполняемых объектами класса NSURLConnection. Объекты класса NSURLCache содержат два параметра, которые управляют размером контейнера в динамической памяти (кэш в памяти) и на устройстве хранения (кэш на диске).

Подробнее о классе NSURLCache можно прочитать в официальная документация .

В операционных системах iOS v4.x и более ранних версиях запросы на соединение не кэшировались на устройстве хранения, а параметр класса diskCapacity игнорировался.

Начиная с версии iOS 5 и выше, приложение по умолчанию создает кэш HTTP-запросов на жестком диске мобильного устройства, ограниченный по объему 20 МБ.

А начиная с 6 версии iOS реализована поддержка кэширования запросов по протоколу HTTPS. Представляется уместным отметить, что уязвимости подвержены все мобильные приложения для платформы iOS, которые явно или неявно осуществляют межсетевые запросы с помощью NSURLConnection. В частности, классы межсетевых запросов популярной библиотеки AFNetworking являются оболочками NSURLConnection. Таким образом, мобильные приложения, использующие AFNetworking, также потенциально уязвимы.



Как защитить приложение?

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

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { .

[[NSURLCache sharedURLCache] setDiskCapacity:0]; .

}

Используя делегатов, это можно сделать следующим образом.



- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { /* Implement cacheing logic here. */ return nil; // HACK: just do not cache }



Точная настройка с помощью Cache-Control

Вряд ли кто-то назовет упомянутые выше решения элегантными (скорее наоборот).

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

Политика кэширования задается в HTTP-заголовке Cache-Control ( РФК 2616 ).

Чтобы продемонстрировать поведение NSURLCache в зависимости от политики кэширования веб-ресурсов, мы скомпилировали простое приложение для мобильной платформы iOS. Использовался iOS SDK v7.0, а приложение запускалось на симуляторе устройства.



Утечка конфиденциальных данных при кэшировании сетевых запросов на платформе iOS

Рис.

1. Тестирование запуска приложения.

Результаты нашего небольшого исследования представлены в таблице 1. Обратите внимание, что, вопреки распространенному мнению, приложение кэширует межсетевые запросы даже без установленного значения заголовка Cache-Control.

Ресурс Кэш-Контроль Кэшированный
/htbin/мистер необходимо перепроверить Да
/htbin/nocache без кэша Да
/htbin/носторе нет магазина Нет
/htbin/частный частный Да
/htbin/публичный общественный Да
/htbin/woheader Не указан Да
/htbin/неявный максимальный возраст=604800 Да
Таблица 1. Кэширование запросов на диске в зависимости от Cache-Control Таким образом, наиболее разумным решением, направленным на устранение выявленной уязвимости, видится установка значения Cache-Control в значение no-store для запросов, содержащих конфиденциальную информацию.

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

RFC 2616, пункт 14.9.2 14.9.2 Что может храниться в кэшах нет магазина Целью директивы no-store является предотвращение непреднамеренного выпуска или сохранения конфиденциальной информации (например, на резервных лентах).

Директива no-store применяется ко всему сообщению и МОЖЕТ быть отправлена либо в ответе, либо в запросе.

При отправке запроса кэш НЕ ДОЛЖЕН хранить какую-либо часть этого запроса или любого ответа на него.

Если он отправлен в ответе, кэш НЕ ДОЛЖЕН хранить какую-либо часть ни этого ответа, ни запроса, который его идентифицировал.

Эта директива применяется как к общим, так и к общим кэшам.

«НЕ ДОЛЖЕН хранить» в этом контексте означает, что кэш НЕ ДОЛЖЕН намеренно хранить информацию в энергонезависимом хранилище и ДОЛЖЕН сделать все возможное, чтобы удалить информацию из энергозависимого хранилища как можно быстрее после ее пересылки.

Даже если эта директива связана с ответом, пользователи могут явно сохранить такой ответ вне системы кэширования (например, с помощью диалогового окна «Сохранить как»).

Буферы истории МОГУТ хранить такие ответы в рамках своей нормальной работы.

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

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

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



Заключение

В этой статье было показано, что начиная с 5 версии операционной системы iOS при использовании класса NSURLConnection с настройками по умолчанию веб-запросы кэшируются на диске.

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

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

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

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

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

Теги: #информационная безопасность #iOS #Разработка для iOS #мобильные приложения #статический анализ кода #анализ кода #информационная безопасность #анализ безопасности #аудит ИБ

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.