Content Security Policy — это полезное дополнение к безопасности вашего веб-приложения, но его настройка может оказаться непростой задачей. До сих пор.

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

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

В идеальном мире где-то на веб-странице должно быть поле ввода, в которое вы вставляете свой URL-адрес, и оно срабатывает и творит чудеса. К сожалению, это на самом деле невозможно, как вы можете себе представить, поскольку этот сторонний веб-сайт просто не может взаимодействовать с DOM в достаточной степени, чтобы идентифицировать все источники из-за единой политики происхождения.

Вариант 1 — грязный способ

В итоге мы придумали два подхода. Я быстро упомяну первый, так как он был массово заменен сейчас! Мы написали фрагмент JavaScript, который вы могли вставить в свою консоль разработчика, и он будет проходить через DOM, идентифицировать объекты, связанные с CSP, и создавать кандидата заголовка Content-Security-Policy.

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

Вариант 2 — Хороший способ

Политика безопасности контента включает возможность указать местоположение report-uri. Если это указано в заголовке CSP, при возникновении нарушения ваш браузер отправляет HTTP-запрос POST на целевой URL-адрес с объектом JSON, содержащим сведения о нарушении.

Все, что нам нужно было для написания политики, смотрело нам прямо в лицо. Как будто об этом подумал RFC. ;-)

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

Поскольку мы хорошие люди, все это с открытым исходным кодом (и мы приветствуем запросы на внесение изменений в улучшения), и оно также доступно на Docker Hub, так что вы можете запустить свою собственную копию в Docker где-нибудь всего несколькими нажатиями клавиш.

Хватит уже, покажи!!

Идея очень проста: настроить ограничительный CSP только для отчетов и установить report-uri для экземпляра нашего бэкенда генератора CSP. Серверная часть состоит из простого приложения Ruby, которое использует Sinatra для обслуживания двух URL-адресов: /report и /policy. URL-адрес /report должен быть целью для report-uri. /policy используется для создания политики для указанного вами имени хоста.

Пример заголовка ответа HTTP:

Content-Security-Policy-Report-Only: default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; report-uri http://localhost:4567/report;

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

Генерировать нарушения

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

Предупреждение!

Не все люди в Интернете хорошие. Мы уже видели немало запросов, которые выглядят как спам-запросы report-uri. По сути, люди, пытающиеся заставить вас перейти по их ссылкам, когда вы расследуете очевидное нарушение. В report-uri нет аутентификации (хорошо, есть способы, но в данном случае их нет), так что не доверяйте слепо записанной информации. Проверьте его перед использованием.

Мы также не рекомендуем вам оставлять эту службу работающей на неопределенный срок. Он предназначен для помощи в построении CSP, а не для того, чтобы стать частью вашей текущей отчетности о нарушениях. Для этого есть другие сервисы (подсказка https://report-uri.io).

Создайте новую политику безопасности контента

Когда вы закончите, просто зайдите в свой сервер и получите доступ к URL-адресу /policy с аргументом RESTful имени хоста, для которого вы создаете политику.

Например, если вы создаете CSP для www.bbc.co.uk, вы должны перейти по адресу http://localhost:4567/policy/www.bbc.co.uk. Это выдаст ответ JSON со значением заголовка CSP под ключом политики.

По умолчанию CSP Generator не выводит unsafe-inline или unsafe-eval. Если вам это нужно, укажите параметр ?unsafe=1 в запросе выше:

http://localhost:4567/policy/www.bbc.co.uk?unsafe=1

Если вы хотите увидеть пример из реальной жизни, у нас есть работающий экземпляр этого приложения по адресу https://csp.4armed.io с тестовой страницей по адресу https://csp.4armed.io/csptest.html. . Для этой страницы была создана следующая политика:

https://csp.4armed.io/policy/csp.4armed.io

В ходе наших экспериментов мы обнаружили, что генератор CSP покрывает в среднем более 90% необходимой конфигурации CSP. На самом деле, единственное, что нам пока приходится настраивать вручную, — это хеш-значения или значения nonce, если они применимы. Мы все еще дорабатываем CSP для сайта www.4armed.com. Любой, кто запускает сайт WordPress, оценит, насколько это PITA для встроенного скрипта и CSS (настолько, что с момента написания этой статьи мы отказались от WordPress). Мы уже провели рефакторинг больших кусков и отказались от половины аналитики, которую (не) использовали. Это происходит, но это работа в процессе.

Между прочим, Google Analytics является худшим, поскольку мы обнаружили, что каждый домен google.x для конкретной страны в конечном итоге нарушает нашу CSP. Невозможно (по понятным причинам) использовать подстановочный знак в правой части имени хоста, поэтому, если мы не создали CSP, разрешающий скрипт для каждого возможного домена Google для конкретной страны, было бы проще просто удалить GA с сайта.

Докер FTW!

Если вы хотите запустить свой собственный экземпляр сервера, вы можете запустить приложение Sinatra локально. Полная информация об этом представлена ​​на https://github.com/4armed/csp-backend. В качестве альтернативы, настройка Docker Compose, вероятно, является самым простым путем. Полная информация об этом также есть на Github, на этот раз по адресу https://github.com/4armed/csp-generator.

Делаем CSP-разработку еще приятнее

Установка и перенастройка заголовков HTTP-ответа CSP на ваших веб-сайтах может быть обременительной и не лишена риска вызвать проблемы у законных пользователей во время эксперимента. Поэтому мы упростили и этот шаг с помощью нашего расширения Google Chrome для генерации CSP.

Вы можете загрузить это с нашего Github по адресу https://github.com/4armed/csp-generator-extension, и это обеспечивает простой способ взаимодействия с нашим бэкэндом CSP Generator, а также возможность редактирования и тестирования политик на лету прямо в вашем браузер. Реальный веб-сайт никогда не затрагивается, поскольку он перехватывает ответ HTTP и манипулирует заголовками локально для вас. Это выглядит так:

Когда у вас есть CSP, который работает в режиме полного «ВКЛ», вы можете внедрить заголовки в свое реальное веб-приложение и посмотреть, как оно работает для всех.

Мы сделали следующее видео, чтобы быстро продемонстрировать установку и использование расширения Chrome. Полные инструкции по установке есть на странице Github.

Резюме

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

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

Мы надеемся, что вы найдете его полезным.

Первоначально опубликовано на www.4armed.com 8 декабря 2016 г.