Введение
HTTP-заголовки безопасности — это первый рубеж защиты сайта. Они не зависят от кода приложения, настраиваются на уровне веб-сервера и способны:
-
предотвратить XSS и clickjacking-атаки;
-
усилить защищённость сессий и cookie;
-
ограничить работу API и встроенных ресурсов;
-
снизить вероятность эксплуатации уязвимостей браузера.
С их помощью можно сильно уменьшить площадь атаки, при этом не переписывая код сайта.
Почему это важно
1. Защита от атак в браузере
Многие атаки происходят после загрузки страницы — когда злоумышленник пытается внедрить JavaScript, получить доступ к iframe, отправить cookie третьим лицам. Заголовки — это способ сказать браузеру: "Не делай этого".
2. Улучшение безопасности без изменения бэкенда
Если вы не контролируете код (например, это сторонний движок, CMS или SaaS), то заголовки — это единственное, что вы можете использовать.
3. Влияние на SEO
Google оценивает сайт не только по контенту, но и по уровню защиты. Присутствие базовых заголовков (например, HSTS, CSP, X-Content-Type-Options) положительно влияет на оценку доверия к домену.
Чеклист ключевых заголовков безопасности
1. Content-Security-Policy (CSP)
Назначение: защита от 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, чтобы посмотреть, что ломается.
2. Strict-Transport-Security (HSTS)
Назначение: принудительный переход на HTTPS. Предотвращает downgrade-атаки.
Пример настройки:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Что делает:
-
Заставляет браузер обращаться к сайту только по HTTPS.
-
Защищает от MITM-атак на открытых Wi-Fi.
-
Поддерживает механизм preload в браузерах.
Проблемы, которые решает:
-
Возможность перехвата cookie или паролей при первом HTTP-запросе.
-
Уязвимости при редиректе с http → https.
Осторожно: нельзя использовать до полной настройки HTTPS на всех поддоменах.
3. Permissions-Policy (ранее Feature-Policy)
Назначение: контроль над тем, какие API браузера доступны на сайте.
Пример настройки:
Permissions-Policy: camera=(), microphone=(), geolocation=(), fullscreen=(self)
Что делает:
-
Запрещает доступ к камере, микрофону, геолокации.
-
Контролирует, кто может использовать API (например, фреймы).
Реальные кейсы:
-
Блокировка сторонних трекеров в iframe, запрашивающих геоданные.
-
Устранение проблем с попытками запуска fullscreen-режима на сторонних доменах.
4. X-Frame-Options
Назначение: защита от clickjacking (подмена интерфейса через iframe).
Пример настройки:
X-Frame-Options: DENY
или
X-Frame-Options: SAMEORIGIN
Что делает:
-
Запрещает отображение вашего сайта внутри iframe на других доменах.
Проблемы, которые решает:
-
Атаки через скрытые интерфейсы (банковские фишинговые страницы).
-
Маскировка под UI родного сайта.
5. X-Content-Type-Options
Назначение: запрещает браузеру "угадывать" тип содержимого.
Пример настройки:
X-Content-Type-Options: nosniff
Что делает:
-
Защищает от загрузки вредоносных файлов под видом изображений или скриптов.
Реальные проблемы:
-
Злоумышленник загружает SVG с JavaScript — браузер "догадывается", что это скрипт, и исполняет его.
-
С этим заголовком такие атаки блокируются.
6. Referrer-Policy
Назначение: контроль за тем, какие данные об источнике передаются на сторонние сайты.
Пример настройки:
Referrer-Policy: strict-origin-when-cross-origin
Что делает:
-
Не передаёт полные URL и параметры (
utm,session_id) на внешние сайты. -
Помогает сохранить конфиденциальность и не раскрывать структуру сайта.
Промежуточный итог
Эти заголовки являются минимальным набором для любого сайта, включая WordPress, SaaS, лендинги, корпоративные порталы. Их настройка занимает 15–30 минут и повышает защищённость сайта на порядок.
7. Дополнительные HTTP-заголовки безопасности
Cross-Origin-Embedder-Policy (COEP)
Назначение: управление безопасностью встраивания сторонних ресурсов (видео, JS, WebAssembly и др.)
Пример:
Cross-Origin-Embedder-Policy: require-corp
Что делает:
-
Запрещает встраивание ресурсов, не возвращающих заголовок
Cross-Origin-Resource-Policy. -
Необходим для защиты от атак через скрытые iframe и WebAssembly.
Когда нужен: при работе с WebAssembly, SharedArrayBuffer, интенсивных SPA.
Cross-Origin-Opener-Policy (COOP)
Назначение: защита от атак через открытие окон и взаимодействие между ними (спектр атак — XS-Leaks, session sharing и др.)
Пример:
Cross-Origin-Opener-Policy: same-origin
Что делает:
-
Изолирует окна и вкладки от других origin.
-
Предотвращает перехват контекста через JavaScript-атаки.
Expect-CT (устаревший, но всё ещё встречается)
Назначение: контроль использования сертификационных центров и прозрачности сертификатов (Certificate Transparency)
Пример:
Expect-CT: max-age=86400, enforce
Access-Control-Allow-* (CORS)
Назначение: контроль, какие внешние источники могут делать запросы к вашему API.
Пример:
Access-Control-Allow-Origin: https://example.com
Важно: не путать с заголовками безопасности браузера. CORS применяется в API и веб-приложениях, открытых для кросс-доменных запросов.
8. Реальные кейсы: как заголовки решают проблемы
Кейс 1: XSS на лендинге → устранён CSP
Ситуация: на простом WordPress-лендинге был внедрён вредоносный скрипт через незащищённую форму комментариев.
Решение: внедрение Content-Security-Policy: default-src 'self' заблокировало скрипт до фикса уязвимости.
Вывод: CSP защищает, даже если уязвимость есть.
Кейс 2: Open redirect + утечка реферера → исправлено Referrer-Policy
Ситуация: сайт редиректил пользователя на сторонний ресурс и передавал URL со всеми параметрами (utm, email, token).
Решение: установка Referrer-Policy: strict-origin устранила передачу query-части.
Вывод: важна не только защита, но и приватность.
Кейс 3: Clickjacking на внутренней CRM → устранено X-Frame-Options
Ситуация: злоумышленник встраивал CRM во фрейм и имитировал UI (атака clickjacking).
Решение: X-Frame-Options: DENY полностью заблокировал фреймирование.
Вывод: даже внутренние интерфейсы должны быть защищены.
9. Как проверить, какие заголовки уже настроены
- Воспользуйтесь нашим сервисом проверки HTTP заголовков
- Через curl:
curl -I https://example.com -
Через DevTools:
-
Откройте вкладку "Network"
-
Нажмите на запрос → Headers → Response Headers
-
10. Как настроить заголовки: конфигурации
Для Nginx:
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;
Для Apache:
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"
Для PHP (если сервер не даёт настроить заголовки):
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");
11. Стратегия внедрения
Шаг 1. Проверьте текущую конфигурацию
Начните с анализа текущих заголовков и существующих уязвимостей.
Шаг 2. Внедряйте заголовки поэтапно
Особенно это касается CSP — начните с report-only.
Шаг 3. Тестируйте на разных браузерах
Некоторые настройки могут ломать старые версии IE или Safari.
Шаг 4. Добавьте логику отчётов (например, Content-Security-Policy-Report-Only)
Используйте отчёты нарушений в Sentry, Telegram, email или SIEM-систему.
Заключение
HTTP-заголовки безопасности — недорогой и эффективный способ поднять уровень защиты сайта. Они работают независимо от бэкенда, не требуют серьёзной доработки кода и дают защиту от XSS, clickjacking, утечек и нежелательных API.
Но важно помнить: строгие заголовки без понимания логики приложения могут привести к ошибкам, блокировке легитимных скриптов и потере индексации. Внедряйте их последовательно, тестируйте поведение сайта и обновляйте конфигурацию под архитектуру и задачи вашего проекта.
