Лучшие практики безопасности iframe для веб-приложений

Содержание
  1. Что такое iframe в веб-безопасности?
  2. Какие риски безопасности создают элементы iframe?
    1. Кликджекинг
    2. Вредоносный или скомпрометированный сторонний контент
    3. Небезопасный междоменный обмен сообщениями
    4. Раскрытие конфиденциальных данных
    5. Чрезмерные разрешения браузера
  3. Почему реализации iframe терпят неудачу?
  4. Лучшие практики безопасности iframe
    1. Использование атрибута sandbox
    2. Ограничение разрешений iframe
    3. Контроль источников iframe с помощью CSP
    4. Предотвращение несанкционированного фрейминга с помощью frame-ancestors
    5. Валидация источников и данных postMessage()
    6. Разрешение только для надежных источников iframe
    7. Предотвращение размещения конфиденциальных данных в URL-адресах элементов iframe
    8. Применение глубокой эшелонированной защиты к конфиденциальным действиям
    9. Тестирование поведения iframe при изменениях в приложении
  5. Пример безопасного iframe
  6. Как тестирование безопасности приложений помогает выявлять риски iframe
  7. Чек-лист безопасности iframe
  8. Вывод: безопасное использование iframe требует явного доверия
    1. Запрос на бесплатное тестирование Invicti

Элементы iframe облегчают встраивание стороннего контента и сервисов, однако в то же время создают новые границы доверия и риски на уровне браузера. В этой статье рассматриваются способы защиты реализаций iframe с помощью изоляции (sandboxing), политики защиты контента (Content Security Policy), ограничений фрейминга, более безопасного обмена сообщениями между разными источниками (cross-origin) и тестирования безопасности приложений.

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

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

Небезопасные реализации iframe могут способствовать кликджекингу, небезопасному междоменному обмену сообщениями (cross-origin messaging), раскрытию данных и другим браузерным рискам. Безопасная реализация требует большего, чем просто доверие к поставщику контента. Командам необходимо ограничивать возможности iframe, контролировать источники для загрузки, предотвращать несанкционированный фрейминг, проверять сообщения и тестировать конечное поведение приложения.

Что такое iframe в веб-безопасности?

Элемент iframe – это HTML-элемент, который встраивает одну веб-страницу внутрь другой:

<iframe src="https://example.com"></iframe>

Встроенная страница выполняется в отдельном контексте просмотра. Когда родительская страница и содержимое iframe происходят из разных источников, политика одинакового источника браузера обычно запрещает обоим документам напрямую обращаться к DOM, файлам cookie или состоянию JavaScript друг друга. Такая изоляция важна, но она не представляет собой полноценную границу безопасности. Элемент iframe все еще может:

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

Точные возможности зависят от конфигурации iframe, встроенного приложения, источника контента и политик безопасности браузера..

Какие риски безопасности создают элементы iframe?

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

Кликджекинг

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

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

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

Вредоносный или скомпрометированный сторонний контент

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

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

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

Небезопасный междоменный обмен сообщениями

Родительские страницы и элементы iframe часто обмениваются данными с помощью API window.postMessage().

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

К распространенным ошибкам относятся:

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

Небезопасная обработка сообщений может привести к утечке данных или создать вектор ввода для межсайтового скриптинга (XSS) и других уязвимостей логики приложения.

Раскрытие конфиденциальных данных

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

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

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

Чрезмерные разрешения браузера

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

Предоставление широких разрешений увеличивает потенциальное влияние вредоносного или скомпрометированного контента.

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

Почему реализации iframe терпят неудачу?

Большинство сбоев в безопасности iframe возникает из-за чрезмерного доверия или слишком широкой конфигурации. Разработчики могут предполагать, что известный сторонний поставщик всегда является безопасным, полагаться только на политику одинакового источника (same-origin policy) или активировать сразу несколько возможностей iframe для ускорения интеграции.

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

К распространенным причинам относятся:

  • Пропуск атрибута sandbox.
  • Добавление ненужных исключений для песочницы.
  • Предоставление пользователям возможности контролировать источники для iframe.
  • Использование широких выражений для источников в политике Content Security Policy (CSP).
  • Отсутствие ограничений относительно того, какие сайты могут встраивать страницы с конфиденциальными данными.
  • Принятие событий postMessage() от любого источника.
  • Передача конфиденциальных данных через URL-адреса.
  • Сохранение неиспользуемых сторонних встраиваний в среде продакшн.

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

Лучшие практики безопасности iframe

Использование атрибута sandbox

Атрибут sandbox ограничивает возможности фреймированного контента. Пустой атрибут применяет широкий набор ограничений:

<iframe src="https://widgets.example.com" sandbox></iframe>

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

<iframe 
  src="https://widgets.example.com" 
  sandbox="allow-scripts allow-forms">
</iframe>

Доступные ограничения и исключения охватывают такие действия, как:

  • Выполнение скриптов.
  • Отправка форм.
  • Загрузки.
  • Всплывающие окна.
  • Навигация верхнего уровня.
  • Обработка в пределах одного источника.

Начинать необходимо с наиболее строгой конфигурации, добавляя разрешения только тогда, когда интеграция не может функционировать без них. Особой осторожности требует сочетание allow-scripts и allow-same-origin. Если контент из того же источника получает оба разрешения, он может удалить атрибут sandbox и избежать установленных ограничений. По возможности ненадежный фреймированный контент следует предоставлять из отдельного источника и избегать предоставления такой комбинации разрешений.

Ограничение разрешений iframe

Для контроля доступа к функциям браузера необходимо использовать атрибут allow элемента iframe и заголовок Permissions Policy.

Например:

<iframe
  src="https://widgets.example.com"
  sandbox="allow-scripts allow-forms"
  allow="camera 'none'; microphone 'none'; geolocation 'none'">
</iframe>

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

Контроль источников iframe с помощью CSP

Политика Content Security Policy может ограничивать источники, из которых приложение имеет возможность загружать контент во фреймы.

Директива frame-src контролирует источники iframe:

Content-Security-Policy: frame-src 'self' https://widgets.example.com;

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

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

Предотвращение несанкционированного фрейминга с помощью frame-ancestors

Для того чтобы определить, какие сайты могут размещать страницу внутри iframe, необходимо использовать директиву CSP frame-ancestors.

Чтобы предотвратить любой фрейминг:

Content-Security-Policy: frame-ancestors 'none';

Чтобы разрешить фрейминг только из того же источника:

Content-Security-Policy: frame-ancestors 'self';

Чтобы разрешить конкретный доверенный родительский источник:

Content-Security-Policy: frame-ancestors 'self' https://portal.example.com;

Директива frame-ancestors является основным современным средством контроля для защиты от кликджекинга, поскольку она поддерживает несколько явно указанных источников и гибкие политики.

Более старый заголовок X-Frame-Options может обеспечить дополнительную совместимость:

X-Frame-Options: DENY

или:

X-Frame-Options: SAMEORIGIN

Не следует полагаться на устаревшее значение ALLOW-FROM. Стоит также отметить, что заголовок X-Frame-Options игнорируется, если в браузерах, поддерживающих эту функцию, присутствует директива frame-ancestors.

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

Валидация источников и данных postMessage()

Во время отправки сообщения необходимо указывать точный ожидаемый целевой источник вместо *:

const frame = document.querySelector("#payment-frame");

frame.contentWindow.postMessage(
  { action: "start-payment", orderId: "12345" },
  "https://payments.example.com"
);

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

window.addEventListener("message", (event) => {
  if (event.origin !== "https://payments.example.com") {
    return;
  }

  if (
    typeof event.data !== "object" ||
    event.data === null ||
    event.data.type !== "payment-status"
  ) {
    return;
  }

  // Validate status against expected values in production use
  updatePaymentStatus(event.data.status);
});

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

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

Разрешение только для надежных источников iframe

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

Необходимо использовать фиксированный набор одобренных URL-адресов или сопоставлять известные идентификаторы с заранее определенными источниками на сервере.

Для сторонних поставщиков:

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

Доверие должно быть явным, ограниченным и регулярно пересматриваться.

Предотвращение размещения конфиденциальных данных в URL-адресах элементов iframe

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

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

Следует учитывать атрибут referrerpolicy элемента iframe, когда фреймированному сайту не нужен полный родительский URL-адрес:

<iframe
  src="https://widgets.example.com"
  sandbox="allow-scripts"
  referrerpolicy="strict-origin-when-cross-origin">
</iframe>

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

Применение глубокой эшелонированной защиты к конфиденциальным действиям

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

  • Проверки авторизации для каждого действия.
  • Средства защиты от подделки межсайтовых запросов (CSRF).
  • Повторную аутентификацию для изменений с высоким уровнем риска.
  • Явное подтверждение важных транзакций.
  • Сессионные файлы cookie с атрибутом SameSite.
  • Элементы контроля идемпотентности и защиты от повторного воспроизведения.

Запрос браузера не следует считать безопасным только из-за того, что он поступает из аутентифицированной сессии.

Тестирование поведения iframe при изменениях в приложении

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

Проверки безопасности должны охватывать:

  • Страницы, которые могут быть встроены во фреймы внешними сайтами.
  • Политики frame-src и frame-ancestors в CSP.
  • Поведение X-Frame-Options в случаях использования.
  • Токены песочницы (sandbox) и разрешения браузера.
  • URL-адреса элементов iframe, контролируемые пользователями.
  • Валидацию отправителя и данных в postMessage().
  • Конфиденциальную информацию, которая передается встроенному контенту.
  • Сторонние интеграции, которые больше не требуются.

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

Пример безопасного iframe

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


<iframe
  id="support-form"
  src="https://support.example.com/embedded-form"
  sandbox="allow-scripts allow-forms"
  allow="camera 'none'; microphone 'none'; geolocation 'none'"
  referrerpolicy="strict-origin-when-cross-origin"
  loading="lazy"
  title="Customer support form">
</iframe>

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

Content-Security-Policy: frame-src https://support.example.com; frame-ancestors 'self';

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

Как тестирование безопасности приложений помогает выявлять риски iframe

Тестирование безопасности приложений может помочь командам найти слабые места безопасности, связанные с поведением фрейминга, политиками браузера, входными данными приложения и взаимодействием во время выполнения. Динамическое тестирование безопасности приложений (DAST) проверяет запущенное приложение извне, используя те же интерфейсы, которые доступны пользователям и злоумышленникам.

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

Тестирование может выявить такие проблемы, как:

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

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

Чек-лист безопасности iframe

Перед развертыванием или утверждением интеграции iframe необходимо подтвердить, что:

  • Iframe загружает контент только из одобренного источника.
  • Атрибут sandbox имеет начальные настройки с минимально необходимыми разрешениями.
  • Функции браузера ограничены с помощью атрибута allow или политики Permissions Policy.
  • Директива CSP frame-src ограничивает, какой именно контент может встраивать приложение.
  • Директива CSP frame-ancestors предотвращает встраивание страниц с конфиденциальными данными несанкционированными сайтами.
  • Заголовок X-Frame-Options установлен там, где это оправдано требованиями к совместимости.
  • Механизм postMessage() использует точные целевые источники.
  • Получатели сообщений проверяют параметр event.origin и данные сообщения.
  • Конфиденциальная информация не размещается в URL-адресах элементов iframe.
  • Введенные пользователями данные не могут напрямую контролировать источник iframe.
  • Авторизация на стороне сервера защищает конфиденциальные действия.
  • Интеграция включена в процессы регулярного тестирования и проверок безопасности.

Вывод: безопасное использование iframe требует явного доверия

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

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

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

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

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

Запрос на бесплатное тестирование Invicti

Подписаться на новости