Для обеспечения бесперебойной контекстной аутентификации в различных доменах организации часто встраивают страницы входа в систему в iframe. Однако загрузка контекстов аутентификации внутри сторонних фреймов подвергает пользователей серьезным угрозам, таким как кликджекинг (переопределение пользовательского интерфейса) и несанкционированное создание учетных данных. Для снижения этих рисков браузеры по умолчанию отключают WebAuthn в iframe, работающих в разных источниках. Безопасное снятие этого ограничения требует активных многоуровневых протоколов защиты .
Выявление моделей угроз
Прежде чем включать авторизацию с помощью паролей (WebAuthn) внутри подфреймов, необходимо понять, от каких сценариев злоупотребления вы защищаетесь:
- Отслеживание с помощью внедрения скрытого iframe: злоумышленник запускает запрос WebAuthn со своего собственного домена, используя рекламу или виджет на доверенном сайте, обманом заставляя пользователей авторизоваться с помощью пароля, не видя контекста. Это связывает личность пользователя с учетной записью, контролируемой злоумышленником, для сбора данных.
- Визуальное наложение и кликджекинг (переделка пользовательского интерфейса): вредоносная родительская страница делает невидимым iframe аутентификации с помощью стандартных CSS и накладывает поддельный элемент пользовательского интерфейса, чтобы украсть клик, запускающий процесс аутентификации. Это может привести к перехвату сессии или принудительному выполнению несанкционированных действий, если пользователь случайно заполнит запрос.
Для противодействия этим угрозам следуйте этим передовым методам:
Для документа верхнего уровня (верхнего фрейма):
Для встроенного документа (iframe):
- Включить разделенные сторонние файлы cookie
- Защитите конечную точку с помощью политики безопасности контента (Content Security Policy).
- Доверяйте, но проверяйте на стороне сервера.
Для обоих документов:
Включите делегирование с помощью политики разрешений.
Браузеры по умолчанию блокируют доступ к WebAuthn в iframe, содержащих данные из разных источников. Политика разрешений — это единый механизм веб-платформы, позволяющий документу верхнего уровня явно делегировать эти мощные возможности конкретным, доверенным сторонним источникам.
Токены функций
WebAuthn использует два разных токена:
-
publickey-credentials-get: Предоставляет авторизацию для входа в систему с помощью пароля (navigator.credentials.get()). -
publickey-credentials-create: Предоставляет авторизацию для процессов регистрации ключей доступа (navigator.credentials.create()).
Требования для обеспечения возможности
Для включения этих возможностей требуется согласование как в ответе родительского сервера, так и в разметке на стороне клиента:
- Заголовок HTTP-ответа Permissions-policy (родительский сервер) : Родительская страница должна указать разрешенные источники в заголовках своего HTTP-ответа, используя синтаксис структурированных полей .
Permissions-Policy: publickey-credentials-get=(self "https://embedded-auth.example.com")
Политика разрешений: совместимость с publickey-credentials-get:
Политика разрешений: совместимость с publickey-credentials-create:
- Атрибут
allowв HTML: В HTML-разметке элемент<iframe>также должен указывать, что он включает эту функцию.
<iframe src="https://embedded-auth.example.com?nonce=deadbeef12345678&client=https%3A%2F%2Fembedded-auth.example.com" allow="publickey-credentials-get"></iframe>
Совместимость с iframe allow="publickey-credentials-get":
Browser Support
Совместимость с iframe allow="publickey-credentials-create":
Browser Support
Включить разделенные сторонние файлы cookie
Для обеспечения надежного процесса аутентификации необходимо установить и поддерживать сессию внутри встроенного iframe, содержащего данные из других источников. Поскольку современные браузеры перешли к строгим ограничениям на использование сторонних файлов cookie, стандартные механизмы сохранения данных часто блокируются по умолчанию и могут потребовать вызова API доступа к хранилищу для получения доступа.
Для устранения этих препятствий настройте сессионные файлы cookie с атрибутами SameSite: None , Secure и Partitioned . Этот единый механизм платформы обеспечивает сохранение состояния внутри iframe, соблюдая при этом настройки конфиденциальности на уровне браузера.
Установить SameSite: None
SameSite: None явно помечает cookie для межсайтового доступа, позволяя отправлять его с запросами, сделанными из контекста стороннего ресурса (например, iframe). Этот атрибут является необходимым условием для корректной работы cookie в сценариях междоменного доступа, хотя для его принятия современными браузерами он должен сочетаться с атрибутом Secure .
Partitioned набор
Атрибут Partitioned позволяет использовать cookie-файл в режиме CHIPS (Cookies Having Independent Partitioned State) , что дает возможность хранить cookie-файл отдельно для каждого сайта верхнего уровня. Это гарантирует доступность cookie-файла в контексте конкретного iframe стороннего сервиса, обеспечивая сохранение состояния сессии без возможности отслеживания между сайтами. Пользователю придется повторно входить в систему для каждого встроенного элемента на другом сайте.
Защитите конечную точку с помощью политики безопасности контента (Content Security Policy).
В то время как политика разрешений определяет, может ли ваш iframe использовать WebAuthn, политика безопасности контента (CSP) определяет, кому разрешено размещать ваш iframe.
Для точки аутентификации крайне важно обеспечить, чтобы подфрейм входа в систему мог загружаться только на авторизованных партнерских сайтах или на ваших собственных ресурсах, предотвращая несанкционированные попытки кликджекинга еще до того, как они смогут загрузить пользовательский интерфейс.
Используйте frame-ancestors
Директива frame-ancestors определяет допустимые родительские страницы, на которые можно встраивать ваш сайт. Добавив домены в эту директиву, вы можете разрешить встраивание подфрейма входа в систему для определенных доменов.
Content-Security-Policy: frame-ancestors 'self' https://parent-site.example.com;
Политика безопасности контента: совместимость с предками фреймов:
Установить X-Frame-Options
Устаревший заголовок X-Frame-Options поддерживает аналогичные возможности, но только бинарные параметры ( DENY или SAMEORIGIN ). Установите значения CSP frame-ancestors и X-Frame-Options: DENY если браузер не поддерживает CSP. Приоритет CSP всегда отдается тем, кто его поддерживает.
X-Frame-Options: DENY
Совместимость с X-Frame-Options:
Доверяйте, но проверяйте на стороне сервера.
Клиентские проверки браузера оценивают намерения и разрешения, но сервер является окончательным арбитром доверия. Проверьте ответ на сервере проверяющей стороны (RP), чтобы убедиться в действительности и наличии подписи контекста.
Полезная нагрузка клиентских данных
Данные клиента WebAuthn включают параметры, специально разработанные для проверки контекста запроса, отправленного внутри iframe:
-
crossOrigin(логическое значение): указывает, был ли вызван API WebAuthn внутри iframe, находящегося в другом месте. Если ваша архитектура основана на iframe, ваш сервер должен обеспечить, чтобы этот флаг был установлен вtrue. -
topOrigin(строка): Источник контекста верхнего уровня просмотра (то, что отображается в адресной строке браузера). Сервер должен проверить это по списку известных, авторизованных родительских источников.
Контрольный список проверки
Для проверки ответа аутентификатора на вашем сервере выполните следующие действия:
- Проанализируйте и декодируйте подписанные данные
collectedClientDataиз ответа аутентификатора. - Убедитесь, что
typeсоответствует церемонии (webauthn.getилиwebauthn.create). - Подтвердите присутствие пользователя и его подпись.
- Если запрос предназначался для отправки из iframe-структуры:
- Enforce
crossOrigin === true. - Убедитесь, что
topOriginсоответствует вашему разрешенному списку родительских источников.
- Enforce
Устанавливайте безопасные сессии с помощью postMessage()
Для надежного установления сессии iframe должен передать токен аутентификации обратно на родительскую страницу с помощью postMessage() , позволяя родительской странице управлять состоянием сессии в собственном контексте.
Безопасный рабочий процесс
Для установления защищенного сеанса выполните следующие действия:
- Убедитесь, что URL-адрес
srciframe содержит параметры запросаnonceиorigin:- Используйте случайное значение для
nonce.nonceслужит токеном проверки безопасности, гарантирующим, что токен аутентификации, полученный от iframe, действительно соответствует конкретной сессии, инициированной родительской страницей. - В качестве
originиспользуйте домен родительского фрейма. Параметрoriginуказывает источник родительской страницы, позволяя iframe безопасно идентифицировать авторизованный контекст, в который он встроен.
- Используйте случайное значение для
- iframe выполняет аутентификацию WebAuthn с помощью собственного сервера.
Сервер iframe выдает токен, например JWT , который включает в себя
nonce, и перенаправляет на родительскую страницу.// Extract nonce and origin from the URL params const urlParams = new URLSearchParams(window.location.search); const nonce = urlParams.get('nonce'); const origin = urlParams.get('origin'); if (!nonce || !origin) { alert('Nonce or origin is missing in the URL'); return; } // Create a JWT const response = await post('/createToken', { nonce, origin }); const token = response.token; // Post the JWT to the parent frame window.parent.postMessage({ token }, origin);Родительская страница отслеживает событие
message, проверяет источник отправителя и подтверждает подлинность токена.window.addEventListener("message", (event) => { if (event.origin !== "https://embedded-auth.example.com") return; // Verify the received JWT const result = await post('/verifyIdToken', { token: event.data.token, origin: provider.origin, }); });Если JWT-токен успешно подтвержден, родительская страница сохраняет сессию.
И отправитель, и получатель несут совместную ответственность за безопасность:
- Отправитель (iframe): При отправке сообщений всегда указывайте строгий целевой источник (никогда не используйте
"*"). - Получатель (родитель): Всегда проверяйте
event.originпри получении сообщений, чтобы предотвратить подмену источника.
Заключение
Безопасное использование iframe зависит от политики разрешений (Permissions Policy) для включения, политики конфиденциальности (CSP) для ограничения, разделенных сторонних файлов cookie для сохранения сессии, проверки контекста клиента на стороне сервера и передачи сессии с учетом контекста с помощью postMessage() .
Чтобы узнать больше по смежным темам, следите за блогом разработчиков Chrome от Google и изучите дополнительные ресурсы в документации Chrome Developer Identity .