Повторно использовать одноразовый номер сценария CSP на протяжении всего сеанса?

Это продолжение https://github.com/w3c/webappsec-csp/issues/215. arturjanc предложил перенести это обсуждение в stackoverflow.

Мы пытаемся внедрить CSP для сценариев в JSF и не знаем, безопасно ли повторно использовать одноразовый номер сценария на протяжении всего сеанса. Или, как предложил arturjanc, исходный документ отправляет свой текущий одноразовый номер на сервер, который генерирует будущие ответы.

Предполагая, что небезопасно повторно использовать одноразовый номер на протяжении всего сеанса, можно ли просто включить начальный одноразовый номер в скрытую форму ввода, как это реализовано в настоящее время " rel="nofollow noreferrer">здесь. (на данный момент игнорируя уязвимости CSP-заголовка/XSS-инъекций - это всего лишь прототип)

@arturjanc: Хотите еще раз присоединиться?

Изменить: Дополнительные мысли относительно ответа Артурьянка:

Не могли бы вы подробнее рассказать о том, как реализовать одноразовые номера для каждого ответа в типичном приложении JSF в настоящее время, то есть просто иметь одну полную загрузку страницы в самом начале и последующую связь только XHR?

Если я правильно вас понимаю, вы предлагаете всегда повторно отправлять первоначально сгенерированный одноразовый номер в каждом запросе XHR. Однако на практике это практически то же самое, что и одноразовые номера за сеанс, не так ли? Просто сложнее с точки зрения реализации.

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

Установка новых заголовков CSP для каждого XHR-ответа, содержащего только вновь созданный одноразовый номер для каждого ответа, вероятно, не будет работать из-за того, что браузеры обрабатывают несколько заголовков CSP в ответах, объединяя их с использованием стратегии пересечения, т. е. Content-Security-Policy: 'nonce-1' в ответе 1 и Content-Security-Policy: 'nonce-2' в ответе 2. сделает оба одноразовых номера недействительными после ответа 2.


person cnsgithub    schedule 03.05.2019    source источник


Ответы (1)


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

В частности, когда вы включаете одноразовый номер в скрытое поле ввода, это позволяет эксфильтровать значение с помощью злоупотребление селекторами CSS; обратите внимание, что та же самая атака не будет работать против атрибута script#nonce, потому что браузер скрывает значение этого атрибута от DOM для защиты от таких атак.

Моя рекомендация будет двоякой:

  • Попробуйте сделать одноразовый номер для каждого ответа, а не для каждого сеанса. Таким образом, даже если одноразовый номер может быть эксфильтрирован, злоумышленнику будет сложно его повторно использовать.
  • Если вам нужно повторно использовать одноразовый номер, чтобы асинхронно извлекаемая с сервера разметка содержала сценарии с правильным значением одноразового номера, сделайте это, не копируя одноразовый номер в модель DOM. Например, если вы используете XHR для URL-адреса с параметром nonce, сделайте что-то вроде xhr.open("/my/url?nonce=" + document.currentScript.nonce)
person Artur Janc    schedule 07.05.2019
comment
Спасибо, пожалуйста, смотрите мои дополнения к исходному вопросу относительно ваших предложений. (К сожалению, мой ответ слишком длинный для комментариев stackoverflow. Вернемся к github? ;-)) - person cnsgithub; 09.05.2019
comment
К сожалению, мой ответ был слишком длинным для комментариев stackoverflow. Вернемся к github к конкретному обсуждению того, как интегрировать CSP в JSF/PrimeFaces. ? ;-) - person cnsgithub; 09.05.2019
comment
Не уверен, что это все еще активно, но есть ли хороший способ обрабатывать одноразовые номера, когда у вас есть приложение, в котором вы хотите разрешить одновременное открытие нескольких вкладок? Я использую PHP, и одноразовый номер регенерируется при каждой загрузке страницы, поэтому старый одноразовый номер больше не будет действительным. - person SScotti; 15.11.2020
comment
Требование одноразового номера применяется браузером на уровне документа: если данная страница имеет CSP с одноразовым номером, то <script> элементам на этой странице нужно будет установить этот одноразовый номер, но другие документы/вкладки из вашего приложения не будут затронуты. Таким образом, по умолчанию одноразовые номера CSP совместимы с несколькими вкладками — единственное, что нужно сделать вашему приложению, — это убедиться, что для заданного ответа HTTP элементы <script> имеют то же значение одноразового номера, что и значение, установленное в заголовке CSP, доставленном с этим отклик. - person Artur Janc; 16.11.2020