Перейти к основному содержанию
Блог

Веб

Заголовки безопасности: CSP, HSTS и другие — как получить A+ в сканерах

Какие HTTP-заголовки безопасности нужны, от чего защищает каждый и как правильно добавить их в nginx — с готовой конфигурацией.

· 7 мин. чтения

Фото: Estormiz, CC0 · Wikimedia Commons

Заголовки безопасности — дополнительные инструкции, которые сервер отправляет браузеру с каждым ответом. Они говорят браузеру, как защищать страницу: открывать только по HTTPS, не выполнять чужие скрипты, не встраивать страницу в рамку на другом сайте и так далее.

Отсутствие заголовков — один из самых быстро обнаруживаемых недочётов и на экспертизе кибербезопасности, и в открытых сканерах (например, securityheaders.com или Mozilla Observatory). Хорошая новость: добавить их обычно можно несколькими строками конфигурации.

Основные заголовки и их назначение

Strict-Transport-Security (HSTS)

Приказывает браузеру в течение заданного срока открывать этот домен только по HTTPS. Даже если пользователь введёт http://, незашифрованный запрос не уйдёт.

Strict-Transport-Security: max-age=31536000; includeSubDomains

Перед добавлением includeSubDomains убедитесь, что все поддомены работают по HTTPS. Директиву preload добавляйте, только понимая последствия: выход из preload-списка занимает время.

Content-Security-Policy (CSP)

Самый мощный и самый сложный заголовок. Он определяет, из каких источников страница может загружать скрипты, стили, изображения, шрифты и куда может отправлять запросы. Правильно настроенный CSP заметно снижает последствия XSS-уязвимостей.

Строгая стартовая политика:

default-src 'self'; script-src 'self'; style-src 'self';
img-src 'self' data:; font-src 'self'; connect-src 'self';
object-src 'none'; base-uri 'self'; frame-ancestors 'self';
form-action 'self'

Важные моменты:

  • Избегайте 'unsafe-inline' и 'unsafe-eval' — они отменяют большую часть защиты CSP. Если нужен inline-скрипт, используйте nonce или хеш.
  • Внешние сервисы (аналитика, платёжный виджет, карта) добавляйте с точным доменом, а не через *.
  • frame-ancestors защищает от clickjacking и в современных браузерах заменяет X-Frame-Options.

X-Content-Type-Options

X-Content-Type-Options: nosniff

Запрещает браузеру «угадывать» тип файла. Например, загруженный текстовый файл не будет выполнен как скрипт.

X-Frame-Options

X-Frame-Options: SAMEORIGIN

Запрещает открывать страницу внутри <iframe> на других сайтах. Полезно добавить для старых браузеров вместе с frame-ancestors в CSP.

Referrer-Policy

Referrer-Policy: strict-origin-when-cross-origin

При переходе на другой сайт передаётся только домен, а не полный URL с параметрами и токенами.

Permissions-Policy

Permissions-Policy: camera=(), microphone=(), geolocation=()

Отключает возможности браузера, которые сайт не использует. Даже если на страницу попадёт чужой код, он не сможет обратиться к камере или геолокации.

Скрытие версии сервера

По умолчанию nginx показывает свою версию в заголовке Server и на страницах ошибок. Это небольшой, но фиксируемый на экспертизе вид раскрытия информации. Его закрывает server_tokens off;.

Заметка: X-XSS-Protection — устаревший заголовок. Современные браузеры его не поддерживают; добавлять его не обязательно, защиту даёт CSP.

Конфигурация nginx

Добавьте следующий блок внутрь server { ... } (в HTTPS-часть):

server_tokens off;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

Параметр always гарантирует, что заголовки отправляются и в ответах с ошибками (404, 500).

Частая ловушка: наследование add_header

В nginx директивы add_header наследуются вложенным блоком, только если в нём нет ни одного собственного add_header. Если вы напишете location /assets/ { add_header Cache-Control ...; }, в ответах этого location все заголовки безопасности пропадут.

Решение: вынести заголовки в отдельный файл и подключать его там, где нужно.

# в /etc/nginx/snippets/security-headers.conf — строки add_header выше

server {
    include snippets/security-headers.conf;

    location /assets/ {
        include snippets/security-headers.conf;
        add_header Cache-Control "public, max-age=31536000, immutable";
    }
}

Безопасное внедрение CSP

Если сразу включить строгий CSP на существующем сайте, часть функций может сломаться. Поэтому действуйте поэтапно:

  1. Сначала включите политику через заголовок Content-Security-Policy-Report-Only — браузер ничего не блокирует, только записывает нарушения в консоль (или на адрес report-uri).
  2. Несколько дней собирайте нарушения и разбирайте каждое: это действительно нужный источник или лишний/чужой код?
  3. Вынесите inline-скрипты и стили в отдельные файлы или добавьте nonce.
  4. Когда политика станет чистой, переименуйте заголовок в Content-Security-Policy.

Проверка результата

Посмотрите заголовки в браузере или в терминале:

curl -sI https://your-domain.uz | grep -iE "strict|content-security|x-content|x-frame|referrer|permissions|server"

Затем проверьте сайт на securityheaders.com и в Mozilla Observatory. Сканеры время от времени меняют критерии оценки, но обычно для высокой оценки решающее значение имеют HSTS и CSP без 'unsafe-inline'.

Помните: A+ в сканере означает только то, что заголовки настроены правильно. Это не говорит об отсутствии ошибок бизнес-логики или контроля доступа в приложении. Заголовки — лишь один слой защиты.

Итог

Заголовки безопасности — настройка, которая требует мало усилий и даёт ощутимую пользу. Добавьте HSTS, CSP, nosniff, Referrer-Policy, Permissions-Policy и server_tokens off, учтите наследование add_header и сначала обкатайте CSP в режиме report-only.

Хотите проверить заголовки и другие настройки своего сайта? Оставьте заявку на сканирование — Claude AI агент и наш специалист посмотрят конфигурацию и покажут, что нужно исправить.