Content security policy что это
Перейти к содержимому

Content security policy что это

  • автор:

CSP: Политика безопасности контента

В этой статье мы объясним, что такое политика безопасности контента, и опишем как использовать CSP для защиты от некоторых распространённых атак.

Что такое CSP (Content Security Policy)

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

Для включения CSP, ответ должен включать HTTP ответ с заголовком Content-Security-Policy со значением содержащим политику. Сама политика состоит из одной или нескольких директив, разделённых точкой с запятой.

Защита от XSS атак с помощью CSP

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

script-src 'self'

Следующая директива разрешает загрузку скриптов только из определённого домена:

script-src https://scripts.normal-website.com

Следует соблюдать осторожность при разрешении сценариев из внешних доменов. Если у злоумышленника есть какой-либо способ контролировать контент, обслуживаемый из внешнего домена, он может провести атаку. Например, сетям доставки контента (CDN), которые не использую отдельные адреса для каждого клиента, такие как ajax.googleapis.com , нельзя доверять, поскольку третьи стороны могут получить контент на свои домены.

Помимо внесения в белый список определённых доменов, политика безопасности контента (CSP) также предоставляет два других способа указания доверенных ресурсов: одноразовые номера и хэши:

  • Директива CSP может указывать одноразовый номер (случайное значение), и это же значение должно использоваться в теге, загружающем скрипт. Если значения не совпадают, скрипт не будет выполняться. Для эффективного контроля, одноразовый номер должен безопасно генерироваться при каждой загрузке страницы и не должен угадываться злоумышленником.
  • Директива CSP может указывать хэш содержимого доверенного скрипта. Если хэш фактического скрипта не соответствует значению указанному в директиве, то он не будет выполняться. Если содержимое скрипта когда-нибудь изменится, вам конечно же, потребуется обновить хэш-значение, указанное в директиве.

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

Some browsers, such as Chrome, have built-in dangling markup mitigation that will block requests containing certain characters, such as raw, unencoded new lines or angle brackets.

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

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

Противодействие атакам с висячей разметкой с помощью CSP

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

img-src 'self'

Следующая директива позволяет загрузку изображений только из определённого домена:

img-src https://images.normal-website.com

Обратите внимание, что эти политики предотвратят некоторые эксплойты с висячей разметкой, потому что простой способ сбора данных без взаимодействия с пользователем — использование тега img . Однако это не защитит от других эксплойтов, таких, как внедрение тега ссылки с разорванным атрибутом href .

Обход CSP с внедрением политик

Вы можете столкнуться с веб-сайтом, отражающим ввод в фактическую политику, скорее всего, в директиве report-uri . Если сайт отражает параметр, которым вы можете управлять, вы можете ввести точку с запятой, чтобы добавить собственные директивы CSP. Обычно директива report-uri завершает список директив. Это означает, что вам нужно перезаписать существующие директивы, для использования этой уязвимости и обхода политики.

Обычно невозможно перезаписать существующую директиву script-src . Однако недавно в Chrome появилась директива script-src-elem , которая позволяет управлять элементами скрипта, но не событиями. Важно отметить, что эта новая директива позволяет перезаписывать существующие директивы script-src .

Защита от кликджекинга с помощью CSP

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

frame-ancestors 'self'

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

frame-ancestors 'none'

Использование политики безопасности контента для предотвращения кликджекинга более гибко, чем использование заголовка X-Frame-Options , поскольку вы можете указать несколько доменов и использовать подстановочные знаки. Например:

frame-ancestors 'self' https://normal-website.com https://*.robust-website.com

CSP также проверяет каждый фрейм в иерархии родительских фреймов, тогда как X-Frame-Options проверяет только фрейм верхнего уровня.

Рекомендуется использовать CSP для защиты от кликджекинга. Вы также можете комбинировать это с заголовком X-Frame-Options , для обеспечения защиты в старых браузерах, которые не поддерживают CSP, таких, как Internet Explorer.

Дополнительные материалы

  • XSS: Межсайтовые сценарии
  • SOP: Что такое Same-origin policy
  • CSRF: Подделка межсайтовых запросов
  • CSRF: Как предотвратить уязвимость

Content security policy что это

CSP (Content Security Policy) — стандарт защиты сайтов от атак с внедрением контента, например XSS — межсайтового скриптинга. CSP описывает безопасные источники загрузки и блокирует ресурсы, которые не входят в «белый список».

Освойте профессию «Белый хакер»

CSP разработал Роберт Хансен в 2004 году. Сначала протокол появился в Firefox 4, а потом и в других популярных браузерах. А в 2012 году он вошел в список рекомендаций World Wide Web Consortium (W3C, Консорциума Всемирной паутины) — группы организаций, которая занимается разработкой стандартов для Всемирной паутины.

Для чего нужен CSP

По политике безопасности в интернете, каждый сайт должен обращаться только к своим данным (same-origin policy). На практике ресурсы постоянно взаимодействуют с другими источниками: социальными сетями, сервисами метрики, сетями доставки контента и т.д. Это используют злоумышленники. Они внедряют вредоносный код в подгружаемую на сайт внешнюю информацию, которую он считает безопасной. Цель CSP — ограничить список ресурсов, откуда может загружаться контент, например изображения для страницы.

Профессия / 13 месяцев
«Белый» хакер

Взламывайте ПО безнаказанно и за оплату

cables_2 2-PhotoRoom 1 (2)

Как работает CSP

Стандарт CSP сообщает сайту, какие источники данных заслуживают доверия, а какие — нет. Он работает по принципу «Что не разрешено (не упомянуто), то запрещено». Для этого на страницу добавляется HTTP-заголовок Content-Security-Policy и директивы. Каждая директива представляет собой «белый список», в котором через пробел прописаны источники контента. Администратор может дать доступ целому домену, его отдельным поддоменам или конкретной странице, уточнить допустимые правила взаимодействия с ними.

Основные директивы

  • img-src — контролирует использование изображений с внешних ресурсов;
  • media-src — управляет загрузкой медиаконтента (видео, анимации, аудио);
  • script-src — ограничивает источники рабочих сценариев для веб-страницы;
  • frame-src — контролирует подгрузку веб-элементов, вложенных в контекст основной страницы;
  • default-src — резервная директива. Когда браузер или другая программа для работы с веб-страницами просматривает код сайта, то сначала анализирует содержание частных директив. Если информации нет, то обращается к резервной директиве. Например, браузер не «увидел» в img-src источники, из которых можно подгружать изображения. Тогда он обращается к default-src и использует указанный там список.

Правила

  • none запрещает использование ресурсов из всех источников, включая домен сайта;
  • self — разрешает подгружать ресурсы, размещенные на домене защищаемого сайта.

Для каждой директивы должны быть прописаны значения. При этом правил из одной директивы не влияют на указанные в другой. Например, если на сайте в img-src помечено self, а в default-src — self и адрес http://cdn.example.com, то картинки будут загружаться только с собственного домена сайта.

Кроме источников, в директивах также прописываются правила:

  • unsafe-inline разрешает использование инлайн-стилей (когда стиль указан не в отдельном блоке/файле, а непосредственно в коде) и скриптов style и script, атрибутов CSS style, обработчиков событий (onclick, onmouseover и т.д.) и javascript-ссылок. Если это правило не прописано, все они запрещаются автоматически;
  • unsafe-eval применяется в директиве script-src. Когда этого правила нет, запрещается любая динамическая оценка кода (при выполнении).

Разработчики и системные администраторы, которые еще не решили, стоит ли внедрять CSP на сайтах, могут применять директиву Content-Security-Policy-Report-Only. В этом случае система защиты будет отмечать нарушения безопасности и отправлять CSP-отчеты, но не станет блокировать использование ресурсов даже из потенциально опасных источников.

Пример 1

Ограничение источников контента только исходным сервером (без поддоменов). Content-Security-Policy: default-src ‘self’

Можно получать контент с только с доверенного домена и его поддоменов. Content-Security-Policy: default-src ‘self’ *.trusted.com

Пользователи приложения могут вставлять в контент изображения из любых источников, но при этом загружать аудио- и видеофайлы только от доверенных провайдеров. Скрипты можно получать только с конкретного сервера, который содержит доверенный код. Content-Security-Policy: default-src ‘self’; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

  • Изображения будут доступны из любого источника (источник — «*»).
  • Прочие медиафайлы — с media1.com и media2.com (без поддоменов).
  • Исполняемый код — с userscripts.example.com.

Станьте специалистом
по кибербезопасности – научитесь отражать кибератаки и поддерживать безопасность любых IT-систем

От каких атак защищает CSP

XSS (Cross-Site Scripting) — «межсайтовый скриптинг»

На страницу сайта внедряется вредоносный код, связанный с сервером злоумышленника. Браузер доверяет источнику контента и выполняет директивы.

Как защищает CSP: администраторы сервера, на котором расположен сайт, могут составить «белый список» доменов, заслуживающих доверия. Так можно сократить или полностью исключить обращение к источникам потенциально вредоносного скрипта. Радикальный вариант защиты — глобальный запрет на исполнение скриптов.

Перехват пакетов

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

Как защищает CSP: сервер может указать, какие протоколы разрешено использовать. Стратегия безопасности передачи данных отмечает файлы cookie атрибутами secure и автоматически перенаправляет со страниц HTTP на их аналоги HTTPS. Сайты также могут использовать HTTP-заголовок Strict-Transport-Security, чтобы браузеры подключались по зашифрованному каналу. От перехвата пакетов это не защитит, но поможет избежать расшифровки.

Читайте также Кто такой «белый» хакер

Типы потенциально опасного содержимого

Скрипты

Это последовательности действий (сценарии), написанные на JavaScript, PHP, Perl, Python или другом скриптовом языке программирования. Скрипты описывают автоматические действия, которые будет выполнять функциональный элемент сайта — например форма оплаты или обратной связи.

Изображения

Хотя картинка (фото, баннер и т.д.) представляет собой набор пикселей, файл с ней размещается и отображается на сайте с помощью скрипта. Именно в сценарий, по которому работает изображение, злоумышленник может вставить вредоносный код.

Стили

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

Медиа

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

Шрифты

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

Объекты

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

Фреймы

Тегами frame и iframe описываются встраивания одних веб-страниц в контекст других. Например, с их помощью отображаются интерактивные карты с адресом компании в разделе «Контакты» на сайтах. Источник опасности — вложенный в основную страницу веб-документ или объект.

Манифесты

Это веб-приложения, которые пользователь может установить на экран гаджета или десктоп ПК. Они объединяют в себе признаки традиционного сайта и нативного ПО. Источник опасности — как код самого манифеста, так и используемые им сторонние ресурсы.

Читайте также Егор Зайцев: «За день до трудоустройства я провел кибератаку на ресурсы работодателя»

Уязвимости CSP

Несмотря на настройки, CSP можно обойти. Количество «лазеек» зависит от его поддержки браузерами. Например, Internet Explorer использует стандарт частично. В меньшем количестве уязвимости есть в браузерах вроде Google Chrome, Opera, Safari.

JavaScript внутри фрейма

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

Отсутствие CSP в ошибках сервера

Разработчики часто защищают только рабочие страницы. Если злоумышленник пропишет в фрейме страницы с ошибкой 404 (или другой с кодом 4**) свой скрипт, то сможет похитить данные.

Подгрузка скриптов с файлообменников

Некоторые сайты используют облачные хранилища данных (Яндекс.Диск, Google Drive и т.д.) как источники контента. В этом случае злоумышленник может разместить на виртуальном диске вредоносный файл или скрипт, который будет исполняться системой.

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

«Белый» хакер

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

Подробная настройка Content Security Policy (CSP)

Content Security Policy (CSP) — это механизм безопасности веб-приложений, который используется для сокращения рисков, связанных с атаками, такими как внедрение скриптов (XSS) и выполнение нежелательного кода (инъекция). CSP позволяет веб-разработчикам указывать браузерам, из каких источников разрешено загружать ресурсы, такие как скрипты, стили, изображения, шрифты и другие элементы.

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

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

Что дальше?

Окей, мы разобрались с тем что такое CSP, но с чего начать, а самое главное как мы будем тестировать, работает этот механизм или нет?
Я попробую пошагово рассказать свой опыт настройки этого механизма, и что я для этого использовал.
Мое приложение использует стек:
  • React.js
  • Typescript
  • Material UI
  • Styled-components
Так же есть прямой доступ к конфигу webpack с конфигурацией сборки.

При локальной разработке у меня используется сервер на node.js «start»: «node scripts/start.js»

Но для нашего тестирования CSP нам потребуется настраивать заголовки на сервере, и самым популярным решением является поднять локально сервер на nginx вместо нашего скрипта.

Nginx Шаг 1

В зависимости от вашей os, команды по установке и запуску nginx могут немного отличаться. Так как я использую mac os, я устанавливал nginx через brew (https://brew.sh)

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

Для Mac Os nginx лежит по адресу /usr/local/etc/nginx либо /opt/homebrew/etc/nginx/nginx.conf базовый конфиг nginx.conf

Первое что я хотел сделать — чтобы nginx, для начала, просто отдавал мою статику.

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

 worker_processes 1; events < worker_connections 1024; >http < include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server < listen 3000; server_name localhost; location / < root html; index index.html index.htm; >error_page 403 404 500 502 503 504 /index.html; location = / < root html; >> include servers/*; >

В данном случае наш сервер должен отдавать статику по адресу http://localhost:3000/

Теперь можем запустить nginx командой sudo nginx

Если мы перейдем по адресу http://localhost:3000/ то должны увидеть что то вроде этого:

Nginx Шаг 2

Теперь нам нужно сбилдить нашу статику и положить ее в usr/local/var/www или /opt/homebrew/var/www

В моем проекте это делается командой yarn run build

На выходе получаем папку static , берем ее внутренности и перемещаем в usr/local/var/www

После этого перезапускаем nginx командой sudo nginx -s stop && sudo nginx

Теперь на http://localhost:3000 мы должны увидеть наше приложение

P.S Этот шаг нужно повторять каждый раз, когда вы обновляете код своего приложения, если хотите проверить результат

Nginx Шаг 3

Далее будет не лишним настроить протокол https , чтобы наш сайт открывался по https://localhost:3000

Для этого нам нужно сгенерировать ssl сертификат. В терминале переходим в папку, в которую сгенерируем 2 новых файла. Лично мне удобно открыть WebStorm со своим проектом, и использовать встроенный терминал.

Вводим в терминал команду openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem

После выполнения команды жмем enter чтобы скипать шаги до шага Common name .

На этом моменте для Common name вводим 127.0.0.1

чтобы установить сертификат в корневом хранилище сертификатов вашей ОС или в браузере, чтобы он был надежным.

В корне проекта появиться два файла cert.pem key.pem

Далее нам нужно перенести эти два файла в папку /usr/local/etc/ca-certificates или /opt/homebrew/etc/ca-certificates

И в конфиге nginx добавить следующие поля ниже поля server_name

P.S Опять же путь до файлов может отличаться

 ssl_certificate /usr/local/etc/ca-certificates/cert.pem; ssl_certificate_key /usr/local/etc/ca-certificates/key.pem;

Так же требуется добавить приписку ssl для поля listen

Получиться примерно так:

 worker_processes 1; events < worker_connections 1024; >http < include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server < listen 3000 ssl; server_name localhost; ssl_certificate /usr/local/etc/ca-certificates/cert.pem; ssl_certificate_key /usr/local/etc/ca-certificates/key.pem; location / < root html; index index.html index.htm; >error_page 403 404 500 502 503 504 /index.html; location = / < root html; >> include servers/*; >

Перезапускаем nginx командой sudo nginx -s stop && sudo nginx

Теперь сайт должен открываться на https://localhost:3000

Nginx Шаг 4

По идее сейчас все готово для того чтобы внедрять политику CSP.

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

А работает она с помощью заголовка Content-Security-Policy, мы будем описывать правила, которые браузер должен будет соблюдать, а если какое-либо действие пользователя будет не по правилам — браузер откажется это выполнять.

Настройка начинается с того, что сначала мы запрещаем все, а потом начинаем добавлять исключения.

Начнем с правила script-src оно определяет допустимые источники JavaScript.

В nginx добавляем заголовок со следующим значением:

add_header Content-Security-Policy «script-src ‘self’ ‘unsafe-inline'»;

В коде это выглядит так:

 worker_processes 1; events < worker_connections 1024; >http < include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server < listen 3000 ssl; server_name localhost; ssl_certificate /usr/local/etc/ca-certificates/cert.pem; ssl_certificate_key /usr/local/etc/ca-certificates/key.pem; location / < add_header Content-Security-Policy "script-src 'self' 'unsafe-inline'"; root html; index index.html index.htm; >error_page 403 404 500 502 503 504 /index.html; location = / < root html; >> include servers/*; >

Перезапускаем nginx командой sudo nginx -s stop && sudo nginx

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

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

add_header Content-Security-Policy «script-src ‘self’ ‘unsafe-inline’ https://www.google.com/recaptcha/»;

Перезапускаем nginx командой sudo nginx -s stop && sudo nginx

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

Nginx Шаг 5

Казалось бы мы настроили первое правило script-src — но нет. В нашем правиле есть ключевое слово ‘unsafe-inline’ который означает что мы разрешаем использование всех встроенных скриптов. Использование этого ключевого слова считается небезопасным.

Давайте попробуем удалить это ключевое слово, и посмотреть что будет:

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

Так что же тут случилось, откуда тут вообще взялась эта ошибка?

Так как мы отказались от ключевого слово ‘unsafe-inline’ — то мы отказались и от использования встроенных скриптов. Теперь же нам нужно научиться “помечать” какие встроенные скрипты являются безопасными.

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

Настройка хеша, включает в себя изменение кода как со стороны frontend так и со стороны nginx.

Для начала начнем со стороны frontend. В целом, описанные ниже шаги можно применить на большинство фреймворков и библиотек, так как основные настройки делаются в корневом index.js и в webpack конфиге.

Настройка frontend приложения

Сама настройка заключается в том, что мы должны добавить атрибут nonce=»CSP_NONCE» ко всем встроенным скриптам. Само значение CSP_NONCE на самом деле может быть любым. Это значение нужно для того, чтобы бы в будущем наш nginx находил это значение в статических файлах js, html и заменял на динамический хеш.

Начнем с простого, зайдем в наш index.html файл, и добавим этот атрибут ко всем подключаемым скриптам, стилям и шрифтам. К примеру у меня есть следующие скрипт и шрифт, в которые я добавляю атрибут:

    

Добавляем в наш index.html следующую запись

На эту запись могут ориентироваться некоторые UI библиотеки, например Material UI

Так же добавляем в index.html следующий скрипт

  

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

Далее открываем наш конфиг для webpack, и находим массив с плагинами plugins: []

Как правило в этом месте описаны настройки для различных плагинов eslint, html.

Нам нужно установить плагин html-webpack-inject-attributes-plugin

Подключить его вверху конфига:

И добавить следующую запись последним элементов массива plugins

plugins: [ // . any plugins new HtmlWebpackInjectPlugin(< nonce: "**CSP_NONCE**", >), ]

Так как использую react, у меня есть скрипт scripts/build.js , который запускается командой yarn run build , этот файл используется для сборки приложения в production

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

process.env.INLINE_RUNTIME_CHUNK = "false";

Открываем наш корневой index.js, и в самый вверх добавляем запись:

// eslint-disable-next-line no-undef __webpack_nonce__ = window.__webpack_nonce__;

По идее все эти шаги должны привести к тому, что каждый ваш встроенный скрипт, стиль, включая динамические, будет иметь атрибут nonce :

Nginx Шаг 6

После того как мы добавили nonce ко всем встроенным скриптам и стилям, нужно расширить конфигурацию nginx, и добавить:

Два поля в раздел location :

sub_filter **CSP_NONCE** $request_id;

Поле sub_filter_once указывает следует ли искать каждую строку для замены один раз.

Поле sub_filter задает строку для замены и строку замены.

То есть мы находим строку **CSP_NONCE** в нашей статике, и заменяем ее на значение переменной $request_id

Из заголовка удаляем строку unsafe-inline которая разрешала нам использование всех встроенных скриптов, и добавляем ‘nonce-$request_id’ и ‘strict-dynamic’

‘strict-dynamic’ — указывает, что доверие, явно предоставляемое скрипту, присутствующему в разметке, путем сопровождения его одноразовым значением или хэшем, должно распространяться на все скрипты, загруженные этим корневым скриптом.

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

 worker_processes 1; events < worker_connections 1024; >http < include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server < listen 3000 ssl; server_name localhost; ssl_certificate /usr/local/etc/ca-certificates/cert.pem; ssl_certificate_key /usr/local/etc/ca-certificates/key.pem; location / < add_header Content-Security-Policy "script-src 'self' 'nonce-$request_id' 'strict-dynamic' https://www.google.com/recaptcha/"; sub_filter_once off; sub_filter **CSP_NONCE** $request_id; root html; index index.html index.htm; >error_page 403 404 500 502 503 504 /index.html; location = / < root html; >> include servers/*; >

После перезапуска nginx, у нас должны пропасть ошибки из консоли.

Nginx Шаг 7

Теперь продолжим добавлять различные директивы, например style-src со значением self

Перезапускаем nginx, обновляем страницу, и смотрим ошибки в консоли.

Скорее всего самые первые ошибки будут указывать на ресурсы, которых нет в white list.

Refused to load the stylesheet » because it violates the following Content Security Policy directive: «style-src ‘self'». Note that ‘style-src-elem’ was not explicitly set, so ‘style-src’ is used as a fallback.

Добавляем ресурс и nonce:

style-src “’self’ ‘nonce-$request_id’ https://*.example.com”

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

worker_processes 1; events < worker_connections 1024; >http < include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server < listen 3000 ssl; server_name localhost; ssl_certificate /opt/homebrew/etc/ca-certificates/cert.pem; ssl_certificate_key /opt/homebrew/etc/ca-certificates/key.pem; set $CSP_SCRIPT_SRC "'self' 'nonce-$request_id' 'strict-dynamic' https://www.google.com/recaptcha/"; set $CSP_STYLE_SRC "'self' 'nonce-$request_id' https://*.example.com"; location / < add_header Content-Security-Policy "script-src $CSP_SCRIPT_SRC; style-src $CSP_STYLE_SRC"; sub_filter_once off; sub_filter **CSP_NONCE** $request_id; root html; index index.html index.htm; >error_page 500 502 503 504 /index.html; location = / < root html; >> include servers/*; >

По такому принципу, вы можете добавить остальные директивы.

У вас получиться примерно так:

#user nobody; worker_processes 1; events < worker_connections 1024; >http < include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server < listen 3000 ssl; server_name localhost; # location of ssl certificate ssl_certificate /usr/local/etc/ca-certificates/cert.pem; # location of ssl key ssl_certificate_key /usr/local/etc/ca-certificates/key.pem; set $CSP_SCRIPT_SRC "'self' 'nonce-$request_id' 'strict-dynamic' https://www.google.com/recaptcha/"; set $CSP_STYLE_SRC "'self' 'nonce-$request_id' https://*.example.com"; set $CSP_CONNECT_SRC "'self' https://*.example.com"; set $CSP_FONT_SRC "'self' https://fonts.gstatic.com/"; set $CSP_IMG_SRC "'self'"; set $CSP_OBJECT_SRC "'self'"; set $CSP_BASE_URI "'self'"; set $CSP_FRAME_SRC "'self' https://www.google.com https://mc.yandex.ru"; set $CSP_MANIFEST_SRC "'self'"; set $CSP_MEDIA_SRC "'self'"; set $CSP_WORKER_SRC "'self'"; set $CSP_FRAME_ANCESTORS "'self'"; location / < add_header Content-Security-Policy "default-src 'none'; script-src $CSP_SCRIPT_SRC; style-src $CSP_STYLE_SRC; connect-src $CSP_CONNECT_SRC; font-src $CSP_FONT_SRC; img-src $CSP_IMG_SRC; object-src $CSP_OBJECT_SRC; base-uri $CSP_BASE_URI; frame-src $CSP_FRAME_SRC; manifest-src $CSP_MANIFEST_SRC; media-src $CSP_MEDIA_SRC; worker-src $CSP_WORKER_SRC; frame-ancestors $CSP_FRAME_ANCESTORS;"; sub_filter_once off; sub_filter **CSP_NONCE** $request_id; root html; index index.html index.htm; >error_page 403 404 500 502 503 504 /index.html; location = / < root html; >> include servers/*; >

В целом на этом моменте можно считать настройку CSP завершенной.

Как работает Content Security Policy (CSP)?

Content Security Policy protecting a webpage.

Проблема безопасности является одной из самых актуальных во всем мире разработки. Разработчики стараются защитить свои веб-сайты от различных угроз, таких как кросс-сайтовые скрипты (XSS). Есть много ошибок, которые могут возникнуть при работе с Content Security Policy (CSP), например, отказ в выполнении встроенного скрипта из-за нарушения директивы CSP.

Content Security Policy (CSP) — это мощный инструмент для усиления безопасности веб-сайтов. Он позволяет контролировать источники, из которых браузер может загружать различные типы контента. Для этого используется специальный HTTP-заголовок Content-Security-Policy .

Принцип работы CSP

CSP работает на основе директив, которые задаются в заголовке Content-Security-Policy . Каждая директива контролирует определенные типы контента, которые могут быть загружены на веб-страницу.

Директивы CSP

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

  • default-src устанавливает правила загрузки для всех типов контента по умолчанию.
  • script-src определяет источники, из которых разрешено загружать скрипты.
  • style-src устанавливает источники для загрузки стилей.
  • img-src контролирует источники изображений.
  • и т.д.

Можно использовать несколько директив в одной политике безопасности. Например:

Content-Security-Policy: default-src 'self'; img-src https://*; child-src 'none'; 

Как использовать CSP

Правила CSP задаются в специальном HTTP-заголовке Content-Security-Policy . Например, чтобы разрешить загрузку контента только с того же источника, можно использовать следующий заголовок:

Content-Security-Policy: default-src 'self' 

Здесь ‘self’ означает, что разрешены только те ресурсы, которые загружаются с того же домена, что и сама страница.

Можно использовать несколько источников, просто перечислив их через пробел:

Content-Security-Policy: default-src 'self' https://example.com 

Порты и протоколы

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

Content-Security-Policy: img-src https://images.example.com 

Использование встроенных стилей и скриптов

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

Content-Security-Policy: script-src 'unsafe-inline' 

Функция eval()

Функция eval() также блокируется по умолчанию из-за риска атак. Если вам необходимо использовать eval() , вы можете разрешить его с помощью директивы unsafe-eval :

Content-Security-Policy: script-src 'unsafe-eval' 

Но помните, что это может существенно снизить уровень безопасности вашего сайта.

Добавить комментарий

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