Использовать одноразовый номер CSP без рендеринга на стороне сервера (файл cookie)

При создании веб-приложения с разделенными внешним и внутренним интерфейсом (без рендеринга на стороне сервера) Я все еще хочу использовать одноразовый номер CSP. Обычно заголовок CSP и html должны содержать один и тот же одноразовый номер, что не проблема с SSR, но кажется невозможным без SSR.

Теперь я подумал о другом способе использования nonce без SSR:

  • Сервер: Помимо отправки одноразового номера с заголовком CSP, также отправьте его в виде файла cookie (все еще меняющегося для каждого запроса!) Это также распространенный подход для CSRF
  • Пользовательский интерфейс: вместо того, чтобы включать <script>, которому требуется одноразовый номер непосредственно внутри html, скорее загружайте его динамически из моего собственного скрипта:
const script = document.createElement('script')
script.setAttribute('src', 'https://example.com')
script.setAttribute('data-csp-nonce', getCspNonceFromCookie())
document.head.appendChild(script);

Является ли это допустимым подходом к этой проблеме? Есть ли опасения по поводу безопасности?


person True Random    schedule 28.08.2019    source источник


Ответы (1)


Ваше решение работает. Один из моих проектов делает это аналогичным образом. Но вы должны установить атрибут nonce вместо data-csp-nonce.

script.setAttribute('nonce', 'THE-GENERATED-NONCE')

Итак, тег script выглядит так:

<script nonce="jETnT70lr0T3Hw4b5WeCjuJ421a3kcBl">
    // ...
</script>

Это безопасно только тогда, когда заголовки, отправляемые сервером, уже содержат content-security-policy, что запрещает внешние скрипты. Например.:

content-security-policy: default-src 'self'; script-src 'self' 'nonce-jETnT70lr0T3Hw4b5WeCjuJ421a3kcBl'; img-src 'self' data:; object-src 'none'
person kmgt    schedule 06.09.2019
comment
Разве создание одноразового номера не является «рендерингом на стороне сервера»? Вы отправляете разные случайно сгенерированные одноразовые номера при каждой загрузке, верно? - person Stephen R; 10.09.2019
comment
Вот так. При каждом запросе должен генерироваться новый одноразовый номер. - person kmgt; 10.09.2019
comment
Я удивлен, что это работает. Я не думал, что вы можете отправлять одноразовые номера CSP после рендеринга - person Stephen R; 10.09.2019
comment
Он хранится в файле cookie (или как метатег). Таким образом, ваш собственный скрипт может получить одноразовый номер оттуда и внедрить тег nonced <script nonce="...">. - person kmgt; 10.09.2019
comment
Мой самый вопрос: может ли злоумышленник использовать тот же файл cookie для внедрения своего собственного сценария так же, как это делаете вы? - person dimisus; 21.11.2020