FastifyMiddleTechnical
Что такое @fastify/helmet и какие заголовки безопасности он устанавливает?
@fastify/helmet — обёртка над helmet.js, добавляет 11 HTTP-заголовков безопасности за одну строку регистрации. Каждый заголовок настраивается или отключается через объект опций плагина.
Что делает плагин
@fastify/helmet регистрирует Fastify-плагин, который подключает библиотеку helmet как middleware. Helmet выставляет HTTP-заголовки, защищающие от распространённых атак: XSS, clickjacking, MIME-sniffing, утечки реферера и других. Без него браузер применяет небезопасные дефолты.
Установка и базовое подключение
npm install @fastify/helmet
import Fastify from 'fastify';
import helmet from '@fastify/helmet';
const app = Fastify();
// Все защитные заголовки с настройками по умолчанию
await app.register(helmet);
await app.listen({ port: 3000 });
Заголовки, устанавливаемые по умолчанию
- Content-Security-Policy — ограничивает источники скриптов, стилей, изображений и фреймов. Дефолтная политика довольно строгая, требует настройки под ваш фронтенд.
- Cross-Origin-Embedder-Policy: require-corp — запрещает загрузку ресурсов из других источников без явного разрешения.
- Cross-Origin-Opener-Policy: same-origin — изолирует окна браузера от cross-origin документов.
- Cross-Origin-Resource-Policy: same-origin — запрещает встраивание ресурса в другие origin.
- Origin-Agent-Cluster: ?1 — требует изолированного агент-кластера.
- Referrer-Policy: no-referrer — не передаёт URL страницы в заголовке Referer.
- Strict-Transport-Security — принудительно переключает браузер на HTTPS (HSTS). В дефолте:
max-age=15552000; includeSubDomains. - X-Content-Type-Options: nosniff — запрещает браузеру угадывать MIME-тип.
- X-DNS-Prefetch-Control: off — отключает DNS-предзагрузку.
- X-Download-Options: noopen — запрещает IE автоматически открывать загрузки.
- X-Frame-Options: SAMEORIGIN — запрещает встраивание страницы в iframe с другого origin (защита от clickjacking).
- X-Permitted-Cross-Domain-Policies: none — запрещает Adobe Flash/Acrobat доступ к cross-domain данным.
- X-XSS-Protection: 0 — намеренно отключает устаревший XSS-фильтр IE/Chrome, который сам создавал уязвимости.
Тонкая настройка CSP
Content-Security-Policy требует тщательной конфигурации под ваш проект:
await app.register(helmet, {
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'nonce-{nonce}'", 'https://cdn.example.com'],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', 'https:'],
connectSrc: ["'self'", 'https://api.example.com'],
fontSrc: ["'self'", 'https://fonts.gstatic.com'],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
},
// Отключить COEP если нужны сторонние ресурсы без CORP-заголовка
crossOriginEmbedderPolicy: false,
// Настроить HSTS
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
});
Отключение отдельных заголовков
await app.register(helmet, {
// Отключить X-DNS-Prefetch-Control
dnsPrefetchControl: false,
// Отключить X-Frame-Options (если используете CSP frame-ancestors вместо него)
frameguard: false,
});
Подводные камни
- CSP ломает инлайн-скрипты — дефолтная политика запрещает
'unsafe-inline'; инлайновые обработчики onclick и style-атрибуты перестанут работать. Используйте nonce или хэш. - COEP и сторонние ресурсы —
Cross-Origin-Embedder-Policy: require-corpблокирует загрузку изображений, шрифтов и скриптов со сторонних CDN, у которых нет заголовкаCross-Origin-Resource-Policy. Часто приходится отключать. - HSTS и HTTP-среды разработки — не включайте HSTS локально; браузер запомнит директиву и перестанет ходить по HTTP, что ломает dev-окружение.
- X-Frame-Options vs CSP frame-ancestors — используйте один из механизмов, не оба. При наличии
frame-ancestorsв CSP браузеры игнорируютX-Frame-Options. - Порядок регистрации — helmet должен быть зарегистрирован до роутов; иначе заголовки не добавятся к ответам.
- Не заменяет CSP-аудит — плагин добавляет заголовки, но не анализирует HTML. Проводите CSP-аудит с report-uri или report-to.
- crossOriginOpenerPolicy ломает OAuth popup — если вы открываете OAuth в popup-окне,
COOP: same-originобрывает связь между окнами; отключите или смените политику наsame-origin-allow-popups. - Версии helmet и @fastify/helmet расходятся — всегда смотрите, на какую мажорную версию helmet опирается плагин; API директив менялось между helmet 5, 6 и 7.
Common mistakes
- Дает общий ответ про Node.js и не называет конкретные API Fastify.
- Не объясняет, где в lifecycle находится @fastify/helmet.
- Не разделяет validation, authorization, business logic и persistence.
- Игнорирует ошибки, лимиты входных данных, observability и тестирование.
What the interviewer is testing
- Может объяснить @fastify/helmet на примере кода.
- Называет ключевые API: @fastify/helmet.
- Использует точные API Fastify, а не вымышленные hooks/decorators/methods.
- Видит production-риски: безопасность, отказоустойчивость, логирование и тесты.