Простой способ настроить Content Security Policy (CSP) для сайта

Зачем?

Настройка Content Security Policy для сайта — не мелочь, а необходимость. Мы не можем знать, что на той стороне у клиента, а это вполне может быть зараженный браузер, зараженные плагины и, в общем, что угодно. Выглядеть это может так: клиент открывает сайт, а вместо ваших рекламных блоков там чужие. Или клиент хочет куда-то нажать, но подгруженный кликандер злоумышленника перехватывает клик и отправляет клиента на левый сайт (возможно, вы найдете переходы на такие сайты в своей статистике LiveInternet).

Content Security Policy защищает пользователя от подобных атак, в явном виде указывая браузеру, откуда разрешено загружать тот или иной контент. Уже два года назад более половины используемых браузеров поддерживали CSP. Сейчас доля поддержки CSP 1.0 приближается к 90% (см. статистику тут).

Как настроить?

Главное при настройке CSP — это определить список всех доменов и типов контента, которые сайту дозволено загружать с этих доменов (включая всевозможные сторонние скрипты, кнопочки, виджеты, счетчики). Учитывается также протокол: http и https — разные вещи.

Есть разные подходы к настройке CSP. Например, можно разобраться в синтаксисе и написать политику вручную, поставить на сайт и отлавливать ошибки, чтобы затем добавить в политику что-то забытое. Кто-то вводит дополнительный скрипт типа csp.php, который пишет ошибки в текстовый лог.

Более удобный вариант — это расширение для Chrome CSP Tester (спасибо за него кому-то из Яндекс.Почты). При всей своей невзрачности это прекрасный инструмент — за пять минут вы одновременно составляете политику и разбираетесь в том, как она пишется. Все тестируется у себя в браузере. Пока политика не отлажена, на живой сайт ее ставить не нужно.

Краткая инструкция есть на ГитХабе. Суть: ставим расширение, указываем адрес сайта в виде *://*.mydomain.com/* и начинаем с единственной галочки default-src: self. Включаем расширение (галочка Active), загружаем сайт и смотрим ошибки в консоли разработчика. Если, например, какой-то контент хочет загрузиться во фрейме, а политика не дает, в тексте ошибки будет ссылка на это (frame-src в данном случае — значит, туда нужно добавить адрес источника). После каждого изменения политики не забываем сохраняться.

Адреса перечисляются через пробел, обычно в следующем виде:

  • 'self' — текущий домен, протокол и порт;
  • *.site.com — все поддомены;
  • site.com — домен (во «все поддомены» он не входит);
  • https://*.site.com или https://site.com — аналогично для https.

Для выполнения скриптов, возможно, потребуется добавить 'unsafe-inline' и/или 'unsafe-eval' (подробнее см. в других источниках, это может быть небезопасно).

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

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

Как включить на сайте?

Переключив CSP Tester в Advanced mode, можно увидеть составленную политику в виде текстовой строки. Теперь ее можно добавить в .htaccess:

<IfModule mod_headers.c>
  Header set Content-Security-Policy "..."
</IfModule>

Например:

<IfModule mod_headers.c>
  Header set Content-Security-Policy "default-src 'self'; script-src *.google-analytics.com 'self'; object-src 'self'; style-src 'self'; img-src *; frame-src 'self'"
</IfModule>

Отключаем расширение, загружаем сайт, убеждаемся, что заголовок Content-Security-Policy приходит и еще раз проверяем, нет ли ошибок в консоли.