Когда говорят о безопасности сайта, обычно вспоминают пароли, SQL-инъекции и CSRF. Но есть уровень ниже — HTTP-заголовки безопасности. Это несколько строк конфигурации сервера, которые закрывают целый класс атак: кликджекинг, MIME-sniffing, утечку referrer, XSS.
Заголовки не требуют денег, установки библиотек или переписывания кода. Достаточно один раз правильно настроить сервер — и сайт становится заметно безопаснее. В этой статье — разбор каждого заголовка с примерами конфигурации для Apache и Nginx.
Зачем нужны HTTP-заголовки безопасности
Браузер — это программа, которая доверяет серверу. Если сервер говорит «делай так» — браузер делает. HTTP-заголовки безопасности — это способ сказать браузеру, что разрешено, а что нет.
Например:
- «Не показывай сайт во фрейме на других доменах» — защита от кликджекинга
- «Не угадывай MIME-тип файла» — защита от загрузки поддельных скриптов
- «Всегда используй HTTPS» — защита от downgrade-атак
- «Не передавай referrer на сторонние сайты» — защита приватности
Каждый заголовок закрывает свою уязвимость. Собрать полный набор — задача на 15 минут, а выгода — постоянная.
HSTS — HTTP Strict Transport Security
Что делает: заставляет браузер всегда использовать HTTPS, даже если пользователь ввёл адрес без протокола.
От чего защищает: от downgrade-атак и SSL-stripping. Когда злоумышленник перехватывает первый HTTP-запрос и подменяет ответ, заставляя браузер идти на сайт по незащищённому протоколу.
Как настроить (Apache):
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>
Как настроить (Nginx):
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Параметры:
max-age=31536000— год, стандарт. Можно увеличить до 2 лет.includeSubDomains— применить ко всем поддоменам. Указывайте только если все они работают по HTTPS.preload— добавить в предзагружаемый список браузеров. Требует подачи заявки на hstspreload.org и необратимо.
Важно: включайте HSTS только после того, как убедитесь, что HTTPS работает на всех страницах и поддоменах. Откатить сложно — браузеры будут помнить год.
X-Frame-Options — защита от кликджекинга
Что делает: запрещает показывать сайт во фрейме (iframe) на других доменах.
От чего защищает: от кликджекинга — атаки, когда злоумышленник кладёт ваш сайт в прозрачный iframe поверх своего и заставляет пользователя кликать по невидимым кнопкам.
Как настроить (Apache):
Header always set X-Frame-Options "SAMEORIGIN"
Как настроить (Nginx):
add_header X-Frame-Options "SAMEORIGIN" always;
Варианты:
DENY— запретить фреймы полностью (включая свой домен).SAMEORIGIN— разрешить только со своего домена. Обычно используется.ALLOW-FROM https://example.com— устаревшее и не поддерживается современными браузерами.
Современная альтернатива: заголовок Content-Security-Policy: frame-ancestors 'self' — более гибкий. Но X-Frame-Options нужен для старых браузеров.
X-Content-Type-Options — защита от MIME-sniffing
Что делает: запрещает браузеру угадывать MIME-тип файла. Использует тот, что указан в заголовке Content-Type.
От чего защищает: от атаки, когда злоумышленник загружает файл с расширением .jpg, но с PHP-кодом внутри. Браузер без этой защиты может определить, что это код, и выполнить его.
Как настроить (Apache и Nginx):
Header always set X-Content-Type-Options "nosniff" add_header X-Content-Type-Options "nosniff" always;
Значение всегда одно: nosniff. Других вариантов нет.
Referrer-Policy — контроль утечки referrer
Что делает: управляет тем, какой URL передаётся в заголовке Referer при переходе на другой сайт.
От чего защищает: от утечки приватных URL (например, ссылок с токенами или ?user_id=123) на сторонние ресурсы — аналитику, рекламные сети, партнёрские сайты.
Как настроить (Apache):
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Как настроить (Nginx):
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Значения:
no-referrer— не передавать referrer вообще.no-referrer-when-downgrade— стандарт браузеров, но менее строгий.origin— передавать только домен (без пути).origin-when-cross-origin— свой домен полностью, чужой — только домен.strict-origin— то же, но только при HTTPS→HTTPS.strict-origin-when-cross-origin— рекомендуемое значение. Полный URL для своего сайта, только домен для чужих, ничего при HTTPS→HTTP.
Permissions-Policy — контроль API браузера
Что делает: указывает, какие функции браузера доступны на странице — камера, микрофон, геолокация, вибрация, автоплей и т.д.
От чего защищает: от злоупотребления возможностями браузера. Например, если злоумышленник через XSS-уязвимость встроит скрипт, который запросит доступ к камере — без Permissions-Policy он может получить разрешение.
Как настроить (Apache):
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Как настроить (Nginx):
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Формат: feature=(разрешённые-домены). Пустые скобки = запретить всем, включая свой сайт.
Примеры:
camera=()— запретить камеру.geolocation=(self)— разрешить только своему домену.autoplay=(self "https://video.example.com")— разрешить себе и одному домену.
Что часто запрещают: camera, microphone, geolocation, payment, usb, magnetometer, gyroscope, accelerometer.
Content-Security-Policy — самый мощный, но сложный
Что делает: указывает, откуда браузер может загружать скрипты, стили, картинки, шрифты и другие ресурсы. Это защита «на уровне содержимого».
От чего защищает: от XSS-атак. Если злоумышленник внедрит скрипт через уязвимость — браузер его не выполнит, потому что источник не в белом списке.
Как настроить (Apache):
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com"
Что здесь важно:
default-src 'self'— базовое правило: только свой домен.script-src 'self'— скрипты только со своего домена. Никаких inline-скриптов.style-src 'self' 'unsafe-inline'— стили со своего домена + inline (часто нужно для CMS).img-src 'self' data: https:— картинки со своего домена, data-URI и любые https.
Важное предупреждение: CSP — самый «хрупкий» заголовок. Настроить его неправильно = сломать сайт. Яндекс.Карты, Google Fonts, виджеты соцсетей, аналитика — всё это нужно явно разрешить.
Совет: начните с режима отчётов — Content-Security-Policy-Report-Only. Браузер будет только логировать нарушения, ничего не блокируя. Через пару недель, когда список стабилен — включите полноценный CSP.
Крайне рекомендуемое правило: script-src-attr 'none'. Оно блокирует inline-обработчики вроде onclick="..." — это самая частая точка входа для XSS.
Как проверить свои заголовки
Три способа, от простого к продвинутому:
1. Через DevTools в браузере
F12 → Network → перезагрузи страницу → клик по главному запросу → Response Headers. Найди все заголовки из этой статьи.
2. Через curl в терминале
curl -I https://вашсайт.ru
Покажет все заголовки ответа. Удобно для быстрой проверки.
3. Через онлайн-сервисы
- securityheaders.com — оценка по буквам от A до F. Покажет что уже настроено и что упущено.
- observatory.mozilla.org — глубокий анализ с рекомендациями.
- ssllabs.com/ssltest/ — проверка SSL/TLS-конфигурации.
После правильной настройки вы получите оценку A или A+ на первом сервисе.
Порядок внедрения
Не пытайтесь настроить всё сразу. Начните с простого:
- X-Content-Type-Options: nosniff — 1 минута, ничего не сломает.
- X-Frame-Options: SAMEORIGIN — 1 минута, безопасно для большинства сайтов.
- Referrer-Policy: strict-origin-when-cross-origin — 1 минута.
- Permissions-Policy — 5 минут, укажите что запрещено.
- HSTS — только после полной проверки HTTPS на всех поддоменах.
- CSP — самый последний. Начните с Report-Only. Настройка может занять недели.
Через час у вас будут 4 из 6 заголовков. Это уже сильно повысит безопасность.
Как Kuznya CMS помогает с этим
Мы в Kuznya CMS настроили все базовые заголовки безопасности из коробки — ещё на этапе установки. HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy — уже прописаны в конфигурации. При развёртывании на новом хостинге они начинают работать без дополнительной настройки.
Дополнительно в движке есть ряд встроенных защит: проверка CSRF-токенов на всех формах, ограничение попыток входа, логирование подозрительных действий. Всё это встроено в админку и настраивается через интерфейс.
Если хотите посмотреть, как это работает — откройте витрину готовых сайтов или загляните в документацию.
А если вы ищете инструмент, где безопасность уже настроена и не требует отдельного внимания — посмотрите тарифы Kuznya CMS. Лицензия от 2 000 ₽, работает на одном домене, без ежемесячных платежей.
Чек-лист по заголовкам
- ☐
Strict-Transport-Security— HSTS включён - ☐
X-Frame-Options— SAMEORIGIN или DENY - ☐
X-Content-Type-Options— nosniff - ☐
Referrer-Policy— strict-origin-when-cross-origin - ☐
Permissions-Policy— запрещены камера, микрофон, геолокация - ☐
Content-Security-Policy— настроен или в Report-Only - ☐ Оценка на securityheaders.com — A или A+
Настроенные заголовки — это не «галочка в отчёте безопасности». Это реальная защита, которая работает круглосуточно и не требует вашего участия. Потратьте час один раз — и забудьте о целом классе атак.