HTTP-заголовки безопасности — это первый рубеж защиты сайта. Они не зависят от кода приложения, настраиваются на уровне веб-сервера и способны:
предотвратить XSS и clickjacking-атаки;
усилить защищённость сессий и cookie;
ограничить работу API и встроенных ресурсов;
снизить вероятность эксплуатации уязвимостей браузера.
С их помощью можно сильно уменьшить площадь атаки, при этом не переписывая код сайта.
Многие атаки происходят после загрузки страницы — когда злоумышленник пытается внедрить JavaScript, получить доступ к iframe, отправить cookie третьим лицам. Заголовки — это способ сказать браузеру: "Не делай этого".
Если вы не контролируете код (например, это сторонний движок, CMS или SaaS), то заголовки — это единственное, что вы можете использовать.
Google оценивает сайт не только по контенту, но и по уровню защиты. Присутствие базовых заголовков (например, HSTS, CSP, X-Content-Type-Options) положительно влияет на оценку доверия к домену.
Назначение: защита от XSS, запрет загрузки небезопасных скриптов, фреймов, изображений.
Пример настройки (жёсткий):
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:;
Что делает:
Запрещает загрузку скриптов, CSS и изображений с внешних сайтов.
Блокирует inline-скрипты.
Запрещает eval и другие опасные конструкции.
Проблемы, которые решает:
XSS-атаки, даже если уязвимость есть в коде.
Встраивание вредоносных фреймов и контента.
Кража cookie и токенов через DOM-инъекции.
Совет: начните с режима Content-Security-Policy-Report-Only
, чтобы посмотреть, что ломается.
Назначение: принудительный переход на HTTPS. Предотвращает downgrade-атаки.
Пример настройки:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Что делает:
Заставляет браузер обращаться к сайту только по HTTPS.
Защищает от MITM-атак на открытых Wi-Fi.
Поддерживает механизм preload в браузерах.
Проблемы, которые решает:
Возможность перехвата cookie или паролей при первом HTTP-запросе.
Уязвимости при редиректе с http → https.
Осторожно: нельзя использовать до полной настройки HTTPS на всех поддоменах.
Назначение: контроль над тем, какие API браузера доступны на сайте.
Пример настройки:
Permissions-Policy: camera=(), microphone=(), geolocation=(), fullscreen=(self)
Что делает:
Запрещает доступ к камере, микрофону, геолокации.
Контролирует, кто может использовать API (например, фреймы).
Реальные кейсы:
Блокировка сторонних трекеров в iframe, запрашивающих геоданные.
Устранение проблем с попытками запуска fullscreen-режима на сторонних доменах.
Назначение: защита от clickjacking (подмена интерфейса через iframe).
Пример настройки:
X-Frame-Options: DENY
или
X-Frame-Options: SAMEORIGIN
Что делает:
Запрещает отображение вашего сайта внутри iframe на других доменах.
Проблемы, которые решает:
Атаки через скрытые интерфейсы (банковские фишинговые страницы).
Маскировка под UI родного сайта.
Назначение: запрещает браузеру "угадывать" тип содержимого.
Пример настройки:
X-Content-Type-Options: nosniff
Что делает:
Защищает от загрузки вредоносных файлов под видом изображений или скриптов.
Реальные проблемы:
Злоумышленник загружает SVG с JavaScript — браузер "догадывается", что это скрипт, и исполняет его.
С этим заголовком такие атаки блокируются.
Назначение: контроль за тем, какие данные об источнике передаются на сторонние сайты.
Пример настройки:
Referrer-Policy: strict-origin-when-cross-origin
Что делает:
Не передаёт полные URL и параметры (utm
, session_id
) на внешние сайты.
Помогает сохранить конфиденциальность и не раскрывать структуру сайта.
Эти заголовки являются минимальным набором для любого сайта, включая WordPress, SaaS, лендинги, корпоративные порталы. Их настройка занимает 15–30 минут и повышает защищённость сайта на порядок.
Назначение: управление безопасностью встраивания сторонних ресурсов (видео, JS, WebAssembly и др.)
Пример:
Cross-Origin-Embedder-Policy: require-corp
Что делает:
Запрещает встраивание ресурсов, не возвращающих заголовок Cross-Origin-Resource-Policy
.
Необходим для защиты от атак через скрытые iframe и WebAssembly.
Когда нужен: при работе с WebAssembly, SharedArrayBuffer, интенсивных SPA.
Назначение: защита от атак через открытие окон и взаимодействие между ними (спектр атак — XS-Leaks, session sharing и др.)
Пример:
Cross-Origin-Opener-Policy: same-origin
Что делает:
Изолирует окна и вкладки от других origin.
Предотвращает перехват контекста через JavaScript-атаки.
Назначение: контроль использования сертификационных центров и прозрачности сертификатов (Certificate Transparency)
Пример:
Expect-CT: max-age=86400, enforce
Назначение: контроль, какие внешние источники могут делать запросы к вашему API.
Пример:
Access-Control-Allow-Origin: https://example.com
Важно: не путать с заголовками безопасности браузера. CORS применяется в API и веб-приложениях, открытых для кросс-доменных запросов.
Ситуация: на простом WordPress-лендинге был внедрён вредоносный скрипт через незащищённую форму комментариев.
Решение: внедрение Content-Security-Policy: default-src 'self'
заблокировало скрипт до фикса уязвимости.
Вывод: CSP защищает, даже если уязвимость есть.
Ситуация: сайт редиректил пользователя на сторонний ресурс и передавал URL со всеми параметрами (utm
, email
, token
).
Решение: установка Referrer-Policy: strict-origin
устранила передачу query-части.
Вывод: важна не только защита, но и приватность.
Ситуация: злоумышленник встраивал CRM во фрейм и имитировал UI (атака clickjacking).
Решение: X-Frame-Options: DENY
полностью заблокировал фреймирование.
Вывод: даже внутренние интерфейсы должны быть защищены.
curl -I https://example.com
Через DevTools:
Откройте вкладку "Network"
Нажмите на запрос → Headers → Response Headers
add_header Content-Security-Policy "default-src 'self'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Header always set Content-Security-Policy "default-src 'self'"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
header("Content-Security-Policy: default-src 'self'");
header("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload");
header("Permissions-Policy: geolocation=(), camera=(), microphone=()");
header("X-Frame-Options: DENY");
header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: strict-origin-when-cross-origin");
Начните с анализа текущих заголовков и существующих уязвимостей.
Особенно это касается CSP — начните с report-only
.
Некоторые настройки могут ломать старые версии IE или Safari.
Content-Security-Policy-Report-Only
)Используйте отчёты нарушений в Sentry, Telegram, email или SIEM-систему.
HTTP-заголовки безопасности — недорогой и эффективный способ поднять уровень защиты сайта. Они работают независимо от бэкенда, не требуют серьёзной доработки кода и дают защиту от XSS, clickjacking, утечек и нежелательных API.
Но важно помнить: строгие заголовки без понимания логики приложения могут привести к ошибкам, блокировке легитимных скриптов и потере индексации. Внедряйте их последовательно, тестируйте поведение сайта и обновляйте конфигурацию под архитектуру и задачи вашего проекта.