Рейтинг:1

Допустимо ли использование другого CSP в зависимости от состояния входа в систему и браузера?

флаг bd

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

Соответствующая базовая настройка

  • Drupal 8 со специальным патчем, который делает ckeditor.js передавать одноразовые номера при загрузке своих плагинов, CKEditor используется только зарегистрированными пользователями
  • Комплект безопасности, исправленный, чтобы предоставить перехватчик изменений для директив CSP (https://www.drupal.org/project/seckit/issues/2844205#comment-14217383).
  • Пользовательский код для внесения изменений в отображаемый HTML и конфигурацию CSP из модуля Security Kit.

Предварительные соображения

Я хотел бы не использовать 'небезопасно встроенный' для скриптов, если это возможно, но в конце концов я понял, что это будет работать только для определенных браузеров. Я также хотел бы иметь адекватный CSP для разных ситуаций (разные браузеры, вход в систему и не вход в систему).

Это приводит меня к этой идее для сценарий-источник:

  • с использованием одноразовый номер и «строгий динамический» для браузеров, поддерживающих CSP v3 и некэшируемые страницы
  • использование хэшей для браузеров, поддерживающих CSP v3 и кешируемые страницы
  • с использованием 'небезопасно встроенный' вместе со списком на основе домена для всех других браузеров

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

Что я сделал до сих пор на моем местном тестовом сайте

Я добавил логику, которая использует одноразовый номер и «строгий динамический» для браузеров на основе Chrome для зарегистрированных пользователей, для которых страницы не кэшируются, гарантируя, что одноразовые номера являются новыми и уникальными для каждого запроса. Эта логика основана на строке агента пользователя (я знаю, что это небезопасно, но лучшего решения я не вижу).

Таким образом, в основном, для браузера на основе Chrome, вошедшие в систему пользователи получат заголовок CSP с этими политиками CSP, связанными со сценариями ('небезопасно встроенный' в script-src будет игнорироваться браузерами, поддерживающими 'строгий-динамический'):

script-src 'self' 'unsafe-inline' *.googletagmanager.com *.google-analytics.com 'nonce-SECURENONCE' 'strict-dynamic';
script-src-attr 'небезопасный встроенный';

Анонимные пользователи получат CSP, который выглядит примерно так:

script-src 'self' 'unsafe-inline' *.googletagmanager.com *.google-analytics.com 'sha256-HASH_1' 'sha256-HASH_2' 'sha256-HASH_3' 'sha256-HASH_4' 'sha256-HASH_5' .. .;
script-src-attr 'небезопасный встроенный';

Браузеры, не основанные на Chrome, получают заголовок CSP, который выглядит следующим образом:

script-src 'self' 'unsafe-inline' *.google-analytics.com *.googletagmanager.com;

Я также добавил логику, которая, основываясь на вышеуказанных критериях выбора, добавляет либо одноразовый номер атрибуты для каждого тега скрипта (некэшированные страницы) или хэш-коды для каждого тега скрипта (кэшированные страницы). Это также позволяет мне нормально работать с CKEditor в бэкэнде.

Кажется, он хорошо работает в разных браузерах, которые я тестировал: Brave, Chrome, Edge, Firefox и Safari. Только у трех первых есть CSP, который я считаю безопасным (также проверено с помощью https://csp-evaluator.withgoogle.com/).

Является ли допустимым подходом иметь:

  1. разные CSP для зарегистрированных и анонимных пользователей?
  2. разные CSP для разных браузеров (или на самом деле разные «сообщенные браузеры»)?
флаг cn
Кажется, что ваши основные вопросы применимы к любому веб-сайту, а не к Drupal в частности? Извините, если я ошибаюсь. Однако, если бы они это сделали, это могло бы лучше подойти (и, что более важно, получить лучшие ответы на) переполнение стека.
berliner avatar
флаг bd
@Clive Возможно, ты прав. Однако я надеялся, что CSP могут стать темой для пользователей Drupal в целом, и я также надеялся, что кто-нибудь сможет подтвердить или оспорить мой подход в конкретном контексте Drupal.
Рейтинг:3
флаг th
  1. Полагаться на пользовательский агент ненадежно — например, я изменил пользовательский агент в своем старом браузере, иначе YouTube отказывается работать. Если по результатам анализа отчетов о нарушениях вы измените CSP на такой из моего пользовательского агента, законные пользователи этого браузера могут пострадать.

  2. Использование script-src-attr 'небезопасный встроенный'; откроет дверь для XSS в браузерах на основе Chromium, потому что он позволяет обработчикам событий в тегах (например, onckick="оповещение('XSS')").

  3. Использование 'sha256-ХЭШ' является нет поддерживается для внешний скрипты в Safari/Firefox. Если вы используете его для встроенного <script> только теги, так удобнее 'хэш-значение' как для зарегистрированных, так и для незарегистрированных пользователей (и не использовать 'однократно').
    Вы можете использовать смесь 'нонс-' и 'ша256-' но в случае XSS 'нонс-' могут быть повторно использованы на кешируемых браузером страницах (это сложно и маловероятно).

Вкратце, вы можете использовать CSP в режиме обратной совместимости браузеров:

script-src 'self' 'строгий динамический' *.googletagmanager.com *.google-analytics.com
  'sha256-HASH_1' 'sha256-HASH_2' ...;

или же

script-src 'self' 'строгий динамический' *.googletagmanager.com *.google-analytics.com 'nonce-SECURENONCE';
  • Chrome/Edge/Firefox поддерживает «строгий динамический» (что отменяет любые источники на основе хоста), поэтому фактический CSP будет script-src 'строгий динамический' 'sha256-HASH_1' 'sha256-HASH_2' ...; или же script-src 'строгий динамический' 'nonce-SECURENONCE'; соответственно.

  • Сафари не поддерживает «строгий динамический», поэтому фактический CSP будет script-src 'self' *.googletagmanager.com *.google-analytics.com 'sha256-HASH_1' 'sha256-HASH_2' ...; или же script-src 'self' *.googletagmanager.com *.google-analytics.com 'nonce-SECURENONCE'; соответственно.

  • вам не нужно использовать 'небезопасно встроенный' вообще потому что он отменен 'одноразовое значение' или же 'хэш-значение' тем не мение. На данный момент нет браузеров, которые не поддерживают 'одноразовое значение' / 'хэш-значение'.

Приведенный выше CSP не допускает встроенных обработчиков событий в тегах, но:

  1. CKEditor-5 делает не требует 'небезопасно встроенный' и может быть разрешен с помощью nonce/hash. 'небезопасно встроенный' требуется только для CKEditor-4.

  2. Google Analytics не требует 'небезопасно встроенный' и может быть разрешен с помощью nonce/hash.

  3. Сам Диспетчер тегов Google не требует 'небезопасно встроенный' и может быть разрешен с помощью nonce/hash. 'небезопасно встроенный' для GTM требуется только в том случае, если вы используете настраиваемые встроенные скрипты в «Пользовательских тегах HTML».
    Используя 'одноразовое значение' может быть предпочтительнее, потому что, если скрипт GTM вставлен с одноразовый номер = атрибут, он будет перераспределен на все скрипты, вставленные Диспетчером тегов, кроме «Пользовательских тегов HTML».

  4. Если вы используете встроенные обработчики событий в тегах - 'небезопасно встроенный' является обязательным, так что забудьте о одноразовые номера, хэши и «строгий динамический» жетоны. Поскольку 'небезопасные хэши' не поддерживается Safari, вы не можете безопасно разрешить встроенные обработчики событий в тегах.

berliner avatar
флаг bd
Спасибо за этот обширный ответ. У меня есть сомнения относительно следующих шагов, хотя. Моя идея заключалась в том, чтобы обеспечить максимальную безопасность для современных браузеров и не брать низкую планку только потому, что менее современные браузеры ее не поддерживают. Safari, например, понимает nonce, но не понимает `strict-dynamic`, что делает невозможным (в контексте Drupal) наличие функционирующего бэкенда. С другой стороны, хэши не допускают «наследование» CSP, как одноразовые номера со «строгой динамикой» (афаик). И в Drupal, который до сих пор идет в комплекте с CKEditor 4, я, честно говоря, не вижу способа обойти 'unsafe-inline'.
berliner avatar
флаг bd
Итак, является ли изначально плохим предоставление различных правил CSP на основе пользовательского агента, даже если это ненадежно? Насколько я понимаю, правила CSP с низкой планкой всегда будут применяться в качестве базовых, но пользовательские агенты, сообщающие о том, что они современные, по-прежнему будут получать более безопасные правила. Я не понимаю, как это может создать проблему.

Ответить или комментировать

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