Навигация

HTTP-заголовки безопасности

HTTP security-заголовки — это инструкции, которые сервер отправляет браузеру вместе с ответом. Они не требуют изменений в бизнес-логике, но закрывают целые классы атак: HSTS блокирует downgrade на HTTP, X-Frame-Options — clickjacking, Referrer-Policy — утечку URL, COOP/COEP — cross-origin атаки. Статья систематизирует основные заголовки, их значения и способы настройки в Next.js и Nuxt.

Содержание

  1. Почему заголовки — это важно
  2. Content-Security-Policy
  3. Strict-Transport-Security (HSTS)
  4. X-Frame-Options
  5. X-Content-Type-Options
  6. Referrer-Policy
  7. Permissions-Policy
  8. Cross-Origin-Opener-Policy (COOP)
  9. Cross-Origin-Embedder-Policy (COEP)
  10. Cross-Origin-Resource-Policy (CORP)
  11. Clear-Site-Data
  12. Cache-Control для чувствительных страниц
  13. Как настроить в Next.js и Nuxt
  14. Чек-лист заголовков
  15. Терминология
  16. Ключевые тезисы для интервью
  17. Заключение
  18. Полезные ссылки

Почему заголовки — это важно

HTTP-заголовки безопасности — это инструкции, которые сервер отправляет браузеру вместе с ответом. Они не требуют изменений в бизнес-логике приложения, но эффективно закрывают целые классы атак.

Аналогия: если HTML-страница — это содержимое письма, то security-заголовки — это конверт с пометками: «Не вскрывать», «Только лично в руки», «Вернуть отправителю при нарушении». Браузер читает эти пометки и ведёт себя соответственно.


Content-Security-Policy

Подробно разобран в отдельной статье CSP: глубокое погружение.

Кратко: CSP говорит браузеру, откуда разрешено загружать скрипты, стили, изображения и другие ресурсы. Это вторая линия обороны от XSS.

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'

Strict-Transport-Security (HSTS)

HSTS указывает браузеру, что сайт должен загружаться только по HTTPS. Даже если пользователь введёт http://example.com, браузер автоматически перенаправит на HTTPS.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • max-age — время в секундах, на которое браузер запоминает политику.
  • includeSubDomains — распространяет политику на поддомены.
  • preload — позволяет включить сайт в preload-список браузеров.

Предостережение

Перед включением HSTS убедитесь, что весь сайт работает по HTTPS. Иначе пользователи не смогут зайти.


X-Frame-Options

Запрещает встраивание страницы в <iframe>. Защищает от clickjacking — атаки, при которой злоумышленник накладывает прозрачный iframe с вашим сайтом на свою страницу.

X-Frame-Options: DENY

Возможные значения:

  • DENY — запретить встраивание полностью.
  • SAMEORIGIN — разрешить встраивание только с того же источника.

Современная альтернатива — директива CSP frame-ancestors:

Content-Security-Policy: frame-ancestors 'none'

X-Content-Type-Options

Запрещает браузеру угадывать MIME-тип файла (mime sniffing). Без этого заголовка браузер может интерпретировать, например, загруженный .txt как JavaScript.

X-Content-Type-Options: nosniff

Referrer-Policy

Контролирует, какой URL отправляется в заголовке Referer при переходе на другие сайты.

Referrer-Policy: strict-origin-when-cross-origin
ЗначениеПоведение
no-referrerНе отправлять Referer вообще
strict-origin-when-cross-originНа своём сайте — полный URL, на чужом — только origin
originВсегда отправлять только origin
unsafe-urlВсегда отправлять полный URL (небезопасно)

Рекомендуется strict-origin-when-cross-origin — баланс приватности и функциональности.


Permissions-Policy

Контролирует, какие браузерные API могут использоваться на странице.

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

Если ваше приложение не использует камеру — заблокируйте её. Это уменьшает поверхность атаки и защищает приватность пользователей.


Cross-Origin-Opener-Policy (COOP)

COOP изолирует окно/вкладку от других источников. Защищает от атак через window.opener, таких как tabnabbing.

Cross-Origin-Opener-Policy: same-origin
ЗначениеПоведение
same-originТолько окна с того же origin могут взаимодействовать
same-origin-allow-popupsРазрешить взаимодействие с попапами того же origin
unsafe-noneНет изоляции (по умолчанию)

Cross-Origin-Embedder-Policy (COEP)

COEP требует, чтобы встроенные ресурсы (iframe, изображения, скрипты) разрешали cross-origin embedding через CORP или CORS.

Cross-Origin-Embedder-Policy: require-corp

Вместе с COOP включает так называемый cross-origin isolated режим, который необходим для некоторых мощных API (SharedArrayBuffer, performance.measureUserAgentSpecificMemory и др.).


Cross-Origin-Resource-Policy (CORP)

CORP указывает, кто может встраивать ваши ресурсы на других сайтах.

Cross-Origin-Resource-Policy: same-origin
ЗначениеПоведение
same-originТолько ваш origin
same-siteТот же site (включая поддомены)
cross-originЛюбой origin

Clear-Site-Data

Позволяет серверу приказать браузеру очистить cookie, storage, cache. Полезен при logout.

Clear-Site-Data: "cookies", "storage", "cache"

При выходе из системы это гарантирует, что браузер удалит сессионные данные.


Cache-Control для чувствительных страниц

Не security-заголовок в узком смысле, но важен для защиты данных.

Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
Expires: 0

Используйте для страниц с личными данными, чтобы браузер и прокси не кэшировали их.


Как настроить в Next.js и Nuxt

Next.js

// next.config.js
const securityHeaders = [
  { key: 'X-Frame-Options', value: 'DENY' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
  { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
  { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
  { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },
];

module.exports = {
  async headers() {
    return [{ source: '/(.*)', headers: securityHeaders }];
  },
};

Nuxt

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-security'],
  security: {
    headers: {
      xFrameOptions: 'DENY',
      xContentTypeOptions: 'nosniff',
      referrerPolicy: 'strict-origin-when-cross-origin',
      permissionsPolicy: 'camera=(), microphone=(), geolocation=()',
      strictTransportSecurity: {
        maxAge: 31536000,
        includeSubdomains: true,
      },
      crossOriginOpenerPolicy: 'same-origin',
    },
  },
});

Чек-лист заголовков

  • Content-Security-Policy настроена и протестирована.
  • Strict-Transport-Security включён для HTTPS-only сайтов.
  • X-Frame-Options или frame-ancestors 'none' защищают от clickjacking.
  • X-Content-Type-Options: nosniff установлен.
  • Referrer-Policy ограничивает утечку URL.
  • Permissions-Policy блокирует ненужные API.
  • Cross-Origin-Opener-Policy включён.
  • Для чувствительных страниц Cache-Control: no-store.
  • При logout используется Clear-Site-Data.

Терминология

ТерминЗначение
HSTSHTTP Strict Transport Security — принудительный HTTPS
CSPContent Security Policy
COOPCross-Origin-Opener-Policy — изоляция окон
COEPCross-Origin-Embedder-Policy — требования к встраиваемым ресурсам
CORPCross-Origin-Resource-Policy — политика встраивания ресурсов
ClickjackingАтака через прозрачный iframe
TabnabbingАтака через window.opener открытой вкладки
Mime sniffingОпределение MIME-типа браузером по содержимому
Cross-origin isolatedРежим с COOP + COEP для мощных API

Ключевые тезисы для интервью

  • Security-заголовки — самый дешёвый слой защиты: только конфигурация, никаких изменений в коде; HSTS (Strict-Transport-Security) заставляет браузер использовать HTTPS, X-Content-Type-Options: nosniff запрещает угадывать MIME-тип.
  • X-Frame-Options: DENY и CSP frame-ancestors 'none' защищают от clickjacking; современный подход — frame-ancestors в CSP.
  • Referrer-Policy: strict-origin-when-cross-origin — баланс приватности и функциональности; Permissions-Policy блокирует ненужные API (камера, микрофон, геолокация), уменьшая поверхность атаки.
  • COOP + COEP включают cross-origin isolated режим, необходимый для SharedArrayBuffer; COOP защищает от tabnabbing и атак через window.opener.
  • Clear-Site-Data при logout удаляет cookies, storage и cache — критично для общих устройств; Cache-Control: no-store для чувствительных страниц предотвращает кэширование в браузере и прокси.
  • Все заголовки настраиваются в Next.js middleware и Nuxt server routes; для SOC2/CASA наличие и документирование — стандартный evidence.

Заключение

Security-заголовки — это дешёвый и эффективный способ защиты. Они не заменяют безопасный код, но добавляют несколько независимых слоёв защиты: HSTS против downgrade, frame-ancestors против clickjacking, nosniff против mime sniffing, COOP/COEP против cross-origin атак. Для SOC2 и CASA наличие и документирование этих заголовков — стандартный evidence. Фронтенд-разработчик должен знать, какой заголовок за что отвечает, и уметь настраивать их в своём фреймворке.

Полезные ссылки