← Назад к вопросам

Как использовать helmet middleware для защиты Express приложения?

2.2 Middle🔥 111 комментариев
#Безопасность#Фреймворки и библиотеки

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Helmet Middleware для Express

Helmet - это критически важный middleware для обеспечения безопасности Express приложений. Он устанавливает HTTP заголовки, которые защищают от известных веб-уязвимостей.

Установка и базовое использование

npm install helmet
const express = require("express");
const helmet = require("helmet");

const app = express();

// Применить все защиты по умолчанию
app.use(helmet());

app.get("/", (req, res) => {
  res.send("Protected!");
});

app.listen(3000);

Одна строка app.use(helmet()) включает множество защит.

Что делает Helmet

Helmet устанавливает 15+ защитных заголовков:

# До helmet
curl -I http://localhost:3000
# HTTP/1.1 200 OK
# Content-Type: text/html

# После helmet
curl -I http://localhost:3000
# HTTP/1.1 200 OK
# Strict-Transport-Security: max-age=15552000; includeSubDomains
# X-Content-Type-Options: nosniff
# X-Frame-Options: DENY
# X-XSS-Protection: 0
# Content-Security-Policy: default-src 'self'
# ...(и ещё 10+ заголовков)

Основные защиты

1. Strict-Transport-Security (HSTS)

app.use(helmet.hsts({
  maxAge: 31536000,          // 1 год в секундах
  includeSubDomains: true,   // Применить к поддоменам
  preload: true              // Добавить в HSTS preload list
}));

Это заставляет браузер всегда использовать HTTPS:

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

2. Content Security Policy (CSP)

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],                    // По умолчанию - только от себя
    scriptSrc: ["'self'", "'unsafe-inline'"],  // Скрипты
    styleSrc: ["'self'", "https://fonts.googleapis.com"],  // Стили
    imgSrc: ["'self'", "data:", "https:"],   // Изображения
    connectSrc: ["'self'", "https://api.example.com"],  // XHR/WebSocket
    fontSrc: ["'self'", "https://fonts.gstatic.com"],   // Шрифты
    objectSrc: ["'none'"],                      // Запретить <object>, <embed>
    mediaSrc: ["'self'"],                       // Видео/аудио
    frameSrc: ["'none'"],                       // Запретить <iframe>
  },
  reportUri: "/csp-violation-report"            // Отправлять ошибки сюда
}));

// Обработчик для отчётов о нарушениях CSP
app.post("/csp-violation-report", (req, res) => {
  console.log("CSP Violation:", req.body);
  res.status(204).send();
});

CSP защищает от XSS-атак, ограничивая, где браузер может загружать ресурсы.

3. X-Content-Type-Options (MIME Sniffing)

app.use(helmet.noSniff());
// или явно:
app.use(helmet.noSniff({
  // Пусто - использует дефолт
}));

Отправляет заголовок:

X-Content-Type-Options: nosniff

Без этого браузер может неправильно интерпретировать тип файла (например, CSS как JS).

4. X-Frame-Options (Clickjacking защита)

app.use(helmet.frameguard({
  action: "deny"  // или 'sameorigin', 'allow-from'
}));

Отправляет:

X-Frame-Options: DENY

Это запрещает встраивать страницу в <iframe> другим сайтам (защита от clickjacking).

5. X-XSS-Protection

app.use(helmet.xssFilter());

Отправляет:

X-XSS-Protection: 0

Для современных браузеров это неактуально (используй CSP вместо этого), но для старых браузеров помогает.

6. Referrer Policy

app.use(helmet.referrerPolicy({
  policy: "no-referrer"  // или strict-no-referrer, same-origin, etc
}));

Отправляет:

Referrer-Policy: no-referrer

Контролирует, какую информацию о переходе отправлять.

7. Permissions Policy (ранее Feature Policy)

app.use(helmet.permissionsPolicy({
  directives: {
    geolocation: ["self"],           // Геолокация только с того же оригина
    microphone: [],                   // Микрофон запрещён
    camera: [],                       // Камера запрещена
    payment: ["self"],               // Payment API только с того же оригина
  }
}));

Отправляет:

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

Полный защищённый пример

const express = require("express");
const helmet = require("helmet");
const rateLimit = require("express-rate-limit");
const mongoSanitize = require("express-mongo-sanitize");
const xss = require("xss-clean");

const app = express();

// 1. Helmet - заголовки безопасности
app.use(helmet());

// 2. Кастомизированная CSP для приложения
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: [
      "'self'",
      "https://cdn.jsdelivr.net",      // Для CDN бибилиотек
      "https://code.jquery.com"
    ],
    styleSrc: ["'self'", "'unsafe-inline'"],  // Inline стили (если нужны)
    imgSrc: ["'self'", "data:", "https:"],
    connectSrc: ["'self'", "https://api.example.com"],
    fontSrc: ["'self'", "https://fonts.gstatic.com"],
    objectSrc: ["'none'"],
    frameSrc: ["'none'"],
    reportUri: "/csp-violation-report"
  }
}));

// 3. Защита от MIME sniffing
app.use(helmet.noSniff());

// 4. Защита от clickjacking
app.use(helmet.frameguard({ action: "deny" }));

// 5. HSTS для HTTPS
app.use(helmet.hsts({
  maxAge: 31536000,
  includeSubDomains: true,
  preload: true
}));

// 6. Permissions Policy
app.use(helmet.permissionsPolicy({
  directives: {
    geolocation: ["self"],
    microphone: [],
    camera: []
  }
}));

// 7. Защита от DoS атак
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,  // 15 минут
  max: 100                    // максимум 100 запросов за окно
});
app.use(limiter);

// 8. Парсирование JSON
app.use(express.json());

// 9. Защита от NoSQL injection
app.use(mongoSanitize({
  replaceWith: "_",
  onSanitize: ({ req, key }) => {
    console.warn(`Sanitized key: ${key}`);
  }
}));

// 10. Защита от XSS (дополнительно к CSP)
app.use(xss());

// 11. Отключить header X-Powered-By (не раскрывай технологический стек)
app.disable("x-powered-by");

// 12. CORS - если нужно
const cors = require("cors");
app.use(cors({
  origin: "https://example.com",  // Только доверенные источники
  credentials: true,               // Разрешить cookies
  optionsSuccessStatus: 200
}));

// Обработчик для CSP отчётов
app.post("/csp-violation-report", (req, res) => {
  const violation = req.body["csp-report"];
  console.error("CSP Violation:", {
    blockedUri: violation["blocked-uri"],
    violatedDirective: violation["violated-directive"],
    originalPolicy: violation["original-policy"],
    sourceFile: violation["source-file"],
    lineNumber: violation["line-number"]
  });
  res.status(204).send();
});

app.get("/", (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
      <title>Protected App</title>
      <style>body { font-family: Arial; }</style>
    </head>
    <body>
      <h1>Secure Express App</h1>
      <p>Защищено с помощью Helmet!</p>
    </body>
    </html>
  `);
});

app.listen(3000, () => {
  console.log("Server running on https://localhost:3000");
});

Проверка заголовков

# Посмотреть все заголовки безопасности
curl -I https://localhost:3000 | grep -E "(Strict-Transport|Content-Security|X-|Referrer|Permissions)"

# Или используй онлайн инструмент
# https://securityheaders.com/

Конфигурирование для разных окружений

const helmet = require("helmet");

if (process.env.NODE_ENV === "production") {
  app.use(helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'"],
        imgSrc: ["'self'", "https:"],
        upgradeInsecureRequests: true  // Автоматически HTTPS
      }
    },
    hsts: {
      maxAge: 31536000,
      includeSubDomains: true,
      preload: true
    }
  }));
} else {
  // Development - менее строгие правила для отладки
  app.use(helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", "'unsafe-inline'"],
        styleSrc: ["'self'", "'unsafe-inline'"],
        imgSrc: ["'self'", "data:", "https:"]
      }
    }
  }));
}

Best Practices

  • Всегда используй Helmet - это первая строка защиты
  • Настраивай CSP под свои нужды - слишком строгая политика сломает функциональность
  • Используй HTTPS - Helmet защищает только при HTTPS
  • Сочетай с другими middleware - rate limiting, input validation, CORS
  • Мониторь CSP отчёты - они помогут найти уязвимости
  • Тестируй на securityheaders.com - проверь оценку своего приложения
  • Регулярно обновляй Helmet - уязвимости в заголовках находят постоянно

Helmet - это не серебряная пуля, но обязательный фундамент безопасности любого Express приложения.