Security headers: HSTS, CSP, X-Frame-Options и другие
· 7 мин чтения
Кратко: Security HTTP-заголовки - это строки, которые сервер добавляет к каждому HTTP-ответу, чтобы сказать браузеру, как обращаться с вашим сайтом. Правильно настроенные устраняют целые классы атак (XSS, clickjacking, MITM) - и они бесплатны.
Кратко: Security HTTP-заголовки - это строки, которые сервер добавляет к каждому HTTP-ответу, чтобы сказать браузеру, как обращаться с вашим сайтом. Правильно настроенные устраняют целые классы атак (XSS, clickjacking, MITM) - и они бесплатны.
Почему они важны
Приложение может быть идеально защищено backend-side, но без правильных заголовков всё ещё уязвимо для browser-side атак: cross-site scripting (XSS), clickjacking, protocol downgrade, MIME confusion. Security-заголовки переносят защиту в браузер.
Strict-Transport-Security (HSTS)
Заставляет HTTPS для всех будущих посещений. После первого HTTPS-визита браузер запоминает домен и сам переписывает любую http://-ссылку в https://, даже если пользователь кликнет на плохой ответ.
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
max-age=63072000= действует 2 годаincludeSubDomains= правило действует и для всех поддоменов (внимание: если у вас HTTP-only поддомен, сломает его)preload= позволяет включение в HSTS preload список, встроенный в Chrome / Firefox / Safari
Внимание:
HSTS с preload удаляется из списка 6+ месяцев. Не включайте preload до того, как проверите, что HTTPS работает стабильно и для всех поддоменов.
Content-Security-Policy (CSP)
Самый мощный, но и самый сложный для настройки заголовок. Whitelist того, откуда браузер может загружать скрипты, стили, изображения, iframe-ы. Без CSP атакующий, способный инжектировать <script> тэг, может выполнить любой JS - с CSP только код из одобренных источников.
Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-...'; img-src 'self' data: https://cdn.example.com; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'
Обычные директивы:
default-src 'self'= по умолчанию разрешать только ресурсы из моего доменаscript-src= JS-источники (укажите hash или nonce для inline-скриптов)style-src= CSS-источникиimg-src= изображенияconnect-src= AJAX, WebSocket, EventSourceframe-ancestors 'none'= никто не может встроить страницу в iframe (лучше, чем X-Frame-Options)report-uri /csp-report= браузер отправляет JSON при каждом нарушении (вы ловите в backend и логируете)
X-Frame-Options
Более старая альтернатива frame-ancestors. Защищает от clickjacking - атакующий вставляет вашу страницу как iframe и перекрывает невидимыми кнопками.
X-Frame-Options: DENY
Значения: DENY (никто), SAMEORIGIN (только мой домен), ALLOW-FROM uri (deprecated).
X-Content-Type-Options
X-Content-Type-Options: nosniff
Отключает MIME sniffing - браузер будет уважать Content-Type, который вернул сервер. Без этого атакующий может загрузить файл с неправильным типом (например, изображение, которое на самом деле HTML со скриптом) и браузер может выполнить как web page.
Referrer-Policy
Referrer-Policy: strict-origin-when-cross-origin
Управляет, сколько информации о предыдущей странице браузер отправляет в Referer заголовке при клике. Default в современных браузерах уже strict-origin-when-cross-origin, но явный декларативный заголовок обеспечивает консистентность.
Permissions-Policy
Отключает API, которые вам не нужны - камеру, микрофон, GPS, geolocation. Атакующий через XSS не может запросить эти API.
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
Практическая конфигурация в nginx
server {
listen 443 ssl http2;
server_name example.com;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# CSP обширный - определяйте согласно вашему приложению
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; ..." always;
}
Ключ - always - без него nginx пропускает заголовки при error response (4xx, 5xx).
Аудит текущего состояния
Проще всего через online tool. Наш header check покажет вам, какие заголовки отсутствуют и какие неправильны. Для тщательного аудита и securityheaders.com даёт A-F оценку.
Вывод
Security-заголовки - одна из лучших инвестиций по соотношению усилие к выгоде в области security - обычно полчаса настройки в reverse proxy против целой категории browser-side атак. Аудит раз в полгода в рамках регулярного обслуживания - разумный минимум.
Бесплатный аудит security headers
Без регистрации, результат за три секунды.
Попробуйте ePulz.io бесплатно - 7 дней без банковской карты.
Создать аккаунт