White-Shark
01.07.2026, 17:20
Как настроить заголовки безопасности сайта — обсуждение
Если коротко, заголовки безопасности — это такие специальные HTTP-заголовки, которые сервер отдаёт вместе с ответом. Они подсказывают браузеру, как себя вести с сайтом, чтобы уменьшить риски разных атак типа XSS, clickjacking, подмены контента и прочих зловредных сценариев. Не стоит воспринимать их как панацею, но в связке с другими мерами — это важный элемент, который очень сильно повышает безопасность.
Почему вообще стоит заморачиваться с заголовками безопасности?
Потому что без них браузер будет действовать по умолчанию, а это не всегда безопасно. Например, если не ограничить, откуда можно загружать скрипты и стили, злоумышленник сможет просунуть в код вредоносный JS через уязвимость в каком-нибудь модуле или комментариях и сделать любые нехорошие штуки. Или, например, без запрета на встраивание страницы в iframe кто-то может попытаться замаскировать ваш сайт и поймать клики пользователей (clickjacking). Заголовки не защищают 100%, но делают жизнь хакерам очень сложной.
Основные заголовки безопасности и что они делают
1. Content-Security-Policy (CSP)
Это, пожалуй, самый мощный и в то же время самый комплексный заголовок. Он работает как список правил, откуда браузер может загружать скрипты, стили, изображения, шрифты и даже куда отправлять запросы (например, AJAX). Можно запретить инлайн-скрипты, запрещать подключения к подозрительным доменам и многое другое. Если CSP настроен правильно, весь внешний и даже внутренний зловредный код будет блокироваться. Но тут главное — не переборщить и не заблокировать нужное, иначе сайт поломается.
2. X-Frame-Options
Очень простой заголовок с тремя возможными значениями: DENY (запретить встраивание в iframe вообще), SAMEORIGIN (разрешить встраивание только с того же домена) и ALLOW-FROM (устаревший, но позволяет разрешить отдельные домены). Помогает защититься от кликаджекинга — когда вредоносный сайт пытается спрятать ваш сайт во фрейме и обманом заставить пользователя кликать по невидимым кнопкам.
3. X-Content-Type-Options
Обычно ставим в значение nosniff. Это запрещает браузерам пытаться угадать MIME-тип файлов, а заставляет строго следовать тому, что указано сервером. Помогает избежать того, что браузер ошибочно выполнит файл как скрипт или HTML, если тип указан неправильно.
4. Referrer-Policy
Заголовок, который контролирует, какую информацию о том, откуда пришёл пользователь, браузер передаёт сайтам при переходах. Можно полностью запретить отправлять referrer, можно отправлять только домен, можно полный URL и т.п. Полезно для приватности и чтобы предотвращать утечки внутренней информации.
5. Strict-Transport-Security (HSTS)
Очень важный для безопасности заголовок, который скажет браузеру всегда использовать HTTPS, если сайт доступен через HTTPS. Даже если пользователь прописал в адресной строке http://, браузер сам переключится на https://. Помогает бороться с MITM-атаками и принудительно держать трафик в зашифрованном виде.
Типичные ошибки при настройке заголовков безопасности
- Забыл про обратную совместимость с разными браузерами. Например, CSP поддерживают не все старые браузеры, поэтому надо тестировать.
- Поставил слишком жёсткий CSP, не разрешил загрузку критичных библиотек или шрифтов — и сайт сломался.
- Забыл про inline-стили и скрипты, а CSP их по умолчанию запрещает.
- Применил X-Frame-Options с DENY, а у тебя есть приложения или виджеты, которые должны встраиваться во внешний сайт.
- Не прописал HSTS или прописал без включения опции preload, и браузеры не "запомнили" политику.
- Забыл, что заголовки нужно отдавать не только на главной странице, но и для всех ресурсов.
Практические примеры настройки
1. CSP для сайта с собственными скриптами и Google Fonts
Content-Security-Policy: default-src 'self'; script-src 'self' https://fonts.googleapis.com https://ajax.googleapis.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; font-src https://fonts.gstatic.com; img-src 'self' data:;
- default-src 'self' — все ресурсы по умолчанию разрешены только с твоего домена.
- script-src — разрешено загружать скрипты с собственного домена и с googleapis.
- style-src — разрешены стили с собственного домена, googleapis и inline-стили (они нужны, если сайт использует inline style).
- font-src — шрифты загружаются с googleusercontent.
- img-src — картинки разрешены с собственного домена и data URI (встроенные изображения).
2. Заголовок для защиты от кликаджекинга
X-Frame-Options: SAMEORIGIN
Это запретит загружать твой сайт во фреймы с другого домена, но позволит на твоём же.
3. Повышение безопасности при работе с формами
Добавь:
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer-when-downgrade
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
- nosniff блокирует MIME sniffing,
- no-referrer-when-downgrade гарантирует, что реферер передаётся только к HTTPS страницам,
- HSTS заставит браузер работать только через HTTPS в течение года.
Чек-лист для правильной настройки заголовков безопасности
- Проверить, что сервер отдаёт нужные заголовки при всех ответах (важно для API и статики).
- Настроить CSP с минимальным набором разрешённых источников, при необходимости расширять постепенно.
- Убедиться, что в CSP разрешены inline-стили и скрипты, если у тебя их реально много и без них сайт не работает.
- Добавить X-Frame-Options, если сайт не предполагает встраивание в фреймы.
- Включить X-Content-Type-Options: nosniff для всех ответов с контентом.
- Настроить Referrer-Policy в зависимости от нужд приватности и аналитики.
- Задать HSTS с разумным max-age и включить includeSubDomains и preload, если есть сертификаты для поддоменов.
- Проверить через сервисы типа securityheaders.com или observatory.mozilla.org.
- Тестировать работу сайта после включения каждого заголовка, чтобы не ломать функционал.
FAQ по заголовкам безопасности
- Нужно ли ставить все заголовки сразу?
Можно начать с простого набора — HSTS, X-Frame-Options и X-Content-Type-Options, потом постепенно вводить CSP и Referrer-Policy. Главное — не ломать сайт.
- Что делать, если после CSP на сайте перестали работать скрипты?
Скорее всего, нужно проверить, не запрещён ли загрузка скриптов с нужных источников, и разрешить inline или eval, если они используются (хотя eval лучше по возможности не использовать).
- Как проверить, что заголовки действительно работают?
Можно использовать браузерные девтулзы (Network → Headers), специальные онлайн-сервисы или встроенные инструменты безопасности в браузерах. Также можно проверить, не появляется ли в консоли ошибок, связанных с CSP.
- Почему у меня после добавления HSTS браузер говорит, что сайт недоступен?
Возможно, у тебя нет корректного HTTPS-сертификата или проблемы с SSL/TLS. HSTS заставляет браузер всегда использовать HTTPS, поэтому без правильного сертификата доступ заблокируется.
- Можно ли обойти CSP?
Теоретически можно, если есть уязвимости в самом сайте (например, XSS), но правильно настроенный CSP сильно усложняет злоумышленникам жизнь.
- Зачем нужен Referrer-Policy, если у меня есть HTTPS и CSP?
Referrer-Policy отвечает за приватность и предотвращает утечки информации о том, откуда пришёл пользователь. Даже если используешь HTTPS, в некоторых случаях браузер всё равно может передавать полный URL без ограничений.
Ещё пару слов про реализацию
Если у тебя Apache, то заголовки можно добавить через .htaccess или в конфиге:
Header set X-Frame-Options "SAMEORIGIN"
Header set X-Content-Type-Options "nosniff"
и так далее.
В Nginx — через директивы add_header в конфиге серверного блока:
add_header X-Frame-Options "SAMEORIGIN";
add_header Content-Security-Policy "default-src 'self'; ...";
Важно понимать, что порядок и область применения тоже влияют — заголовки должны отдаваться с кодом 200, не с ошибками 404 или 500.
Подытоживая
Заголовки безопасности — это must-have для любого серьёзного сайта. Они помогают браузеру понимать, что разрешено делать со страницей и ресурсами, а что нет. Особое внимание нужно уделять Content-Security-Policy, он мощный, но и сложный в настройке. Не спеши сразу вываливать там супержёсткие правила — лучше идти маленькими шагами, тестируя, чтобы не сломать функционал. Остальные заголовки повешай без раздумий, они не вызовут проблем, а дадут существенный прирост в безопасности.
Если у кого есть опыт настройки или грабли, на которые наступали, делитесь, обсуждаем!
Если коротко, заголовки безопасности — это такие специальные HTTP-заголовки, которые сервер отдаёт вместе с ответом. Они подсказывают браузеру, как себя вести с сайтом, чтобы уменьшить риски разных атак типа XSS, clickjacking, подмены контента и прочих зловредных сценариев. Не стоит воспринимать их как панацею, но в связке с другими мерами — это важный элемент, который очень сильно повышает безопасность.
Почему вообще стоит заморачиваться с заголовками безопасности?
Потому что без них браузер будет действовать по умолчанию, а это не всегда безопасно. Например, если не ограничить, откуда можно загружать скрипты и стили, злоумышленник сможет просунуть в код вредоносный JS через уязвимость в каком-нибудь модуле или комментариях и сделать любые нехорошие штуки. Или, например, без запрета на встраивание страницы в iframe кто-то может попытаться замаскировать ваш сайт и поймать клики пользователей (clickjacking). Заголовки не защищают 100%, но делают жизнь хакерам очень сложной.
Основные заголовки безопасности и что они делают
1. Content-Security-Policy (CSP)
Это, пожалуй, самый мощный и в то же время самый комплексный заголовок. Он работает как список правил, откуда браузер может загружать скрипты, стили, изображения, шрифты и даже куда отправлять запросы (например, AJAX). Можно запретить инлайн-скрипты, запрещать подключения к подозрительным доменам и многое другое. Если CSP настроен правильно, весь внешний и даже внутренний зловредный код будет блокироваться. Но тут главное — не переборщить и не заблокировать нужное, иначе сайт поломается.
2. X-Frame-Options
Очень простой заголовок с тремя возможными значениями: DENY (запретить встраивание в iframe вообще), SAMEORIGIN (разрешить встраивание только с того же домена) и ALLOW-FROM (устаревший, но позволяет разрешить отдельные домены). Помогает защититься от кликаджекинга — когда вредоносный сайт пытается спрятать ваш сайт во фрейме и обманом заставить пользователя кликать по невидимым кнопкам.
3. X-Content-Type-Options
Обычно ставим в значение nosniff. Это запрещает браузерам пытаться угадать MIME-тип файлов, а заставляет строго следовать тому, что указано сервером. Помогает избежать того, что браузер ошибочно выполнит файл как скрипт или HTML, если тип указан неправильно.
4. Referrer-Policy
Заголовок, который контролирует, какую информацию о том, откуда пришёл пользователь, браузер передаёт сайтам при переходах. Можно полностью запретить отправлять referrer, можно отправлять только домен, можно полный URL и т.п. Полезно для приватности и чтобы предотвращать утечки внутренней информации.
5. Strict-Transport-Security (HSTS)
Очень важный для безопасности заголовок, который скажет браузеру всегда использовать HTTPS, если сайт доступен через HTTPS. Даже если пользователь прописал в адресной строке http://, браузер сам переключится на https://. Помогает бороться с MITM-атаками и принудительно держать трафик в зашифрованном виде.
Типичные ошибки при настройке заголовков безопасности
- Забыл про обратную совместимость с разными браузерами. Например, CSP поддерживают не все старые браузеры, поэтому надо тестировать.
- Поставил слишком жёсткий CSP, не разрешил загрузку критичных библиотек или шрифтов — и сайт сломался.
- Забыл про inline-стили и скрипты, а CSP их по умолчанию запрещает.
- Применил X-Frame-Options с DENY, а у тебя есть приложения или виджеты, которые должны встраиваться во внешний сайт.
- Не прописал HSTS или прописал без включения опции preload, и браузеры не "запомнили" политику.
- Забыл, что заголовки нужно отдавать не только на главной странице, но и для всех ресурсов.
Практические примеры настройки
1. CSP для сайта с собственными скриптами и Google Fonts
Content-Security-Policy: default-src 'self'; script-src 'self' https://fonts.googleapis.com https://ajax.googleapis.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; font-src https://fonts.gstatic.com; img-src 'self' data:;
- default-src 'self' — все ресурсы по умолчанию разрешены только с твоего домена.
- script-src — разрешено загружать скрипты с собственного домена и с googleapis.
- style-src — разрешены стили с собственного домена, googleapis и inline-стили (они нужны, если сайт использует inline style).
- font-src — шрифты загружаются с googleusercontent.
- img-src — картинки разрешены с собственного домена и data URI (встроенные изображения).
2. Заголовок для защиты от кликаджекинга
X-Frame-Options: SAMEORIGIN
Это запретит загружать твой сайт во фреймы с другого домена, но позволит на твоём же.
3. Повышение безопасности при работе с формами
Добавь:
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer-when-downgrade
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
- nosniff блокирует MIME sniffing,
- no-referrer-when-downgrade гарантирует, что реферер передаётся только к HTTPS страницам,
- HSTS заставит браузер работать только через HTTPS в течение года.
Чек-лист для правильной настройки заголовков безопасности
- Проверить, что сервер отдаёт нужные заголовки при всех ответах (важно для API и статики).
- Настроить CSP с минимальным набором разрешённых источников, при необходимости расширять постепенно.
- Убедиться, что в CSP разрешены inline-стили и скрипты, если у тебя их реально много и без них сайт не работает.
- Добавить X-Frame-Options, если сайт не предполагает встраивание в фреймы.
- Включить X-Content-Type-Options: nosniff для всех ответов с контентом.
- Настроить Referrer-Policy в зависимости от нужд приватности и аналитики.
- Задать HSTS с разумным max-age и включить includeSubDomains и preload, если есть сертификаты для поддоменов.
- Проверить через сервисы типа securityheaders.com или observatory.mozilla.org.
- Тестировать работу сайта после включения каждого заголовка, чтобы не ломать функционал.
FAQ по заголовкам безопасности
- Нужно ли ставить все заголовки сразу?
Можно начать с простого набора — HSTS, X-Frame-Options и X-Content-Type-Options, потом постепенно вводить CSP и Referrer-Policy. Главное — не ломать сайт.
- Что делать, если после CSP на сайте перестали работать скрипты?
Скорее всего, нужно проверить, не запрещён ли загрузка скриптов с нужных источников, и разрешить inline или eval, если они используются (хотя eval лучше по возможности не использовать).
- Как проверить, что заголовки действительно работают?
Можно использовать браузерные девтулзы (Network → Headers), специальные онлайн-сервисы или встроенные инструменты безопасности в браузерах. Также можно проверить, не появляется ли в консоли ошибок, связанных с CSP.
- Почему у меня после добавления HSTS браузер говорит, что сайт недоступен?
Возможно, у тебя нет корректного HTTPS-сертификата или проблемы с SSL/TLS. HSTS заставляет браузер всегда использовать HTTPS, поэтому без правильного сертификата доступ заблокируется.
- Можно ли обойти CSP?
Теоретически можно, если есть уязвимости в самом сайте (например, XSS), но правильно настроенный CSP сильно усложняет злоумышленникам жизнь.
- Зачем нужен Referrer-Policy, если у меня есть HTTPS и CSP?
Referrer-Policy отвечает за приватность и предотвращает утечки информации о том, откуда пришёл пользователь. Даже если используешь HTTPS, в некоторых случаях браузер всё равно может передавать полный URL без ограничений.
Ещё пару слов про реализацию
Если у тебя Apache, то заголовки можно добавить через .htaccess или в конфиге:
Header set X-Frame-Options "SAMEORIGIN"
Header set X-Content-Type-Options "nosniff"
и так далее.
В Nginx — через директивы add_header в конфиге серверного блока:
add_header X-Frame-Options "SAMEORIGIN";
add_header Content-Security-Policy "default-src 'self'; ...";
Важно понимать, что порядок и область применения тоже влияют — заголовки должны отдаваться с кодом 200, не с ошибками 404 или 500.
Подытоживая
Заголовки безопасности — это must-have для любого серьёзного сайта. Они помогают браузеру понимать, что разрешено делать со страницей и ресурсами, а что нет. Особое внимание нужно уделять Content-Security-Policy, он мощный, но и сложный в настройке. Не спеши сразу вываливать там супержёсткие правила — лучше идти маленькими шагами, тестируя, чтобы не сломать функционал. Остальные заголовки повешай без раздумий, они не вызовут проблем, а дадут существенный прирост в безопасности.
Если у кого есть опыт настройки или грабли, на которые наступали, делитесь, обсуждаем!