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

Как защитить Node.js приложение от XSS-атак?

2.0 Middle🔥 182 комментариев
#Node.js и JavaScript#Безопасность

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

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

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

Как защитить Node.js приложение от XSS-атак?

XSS (Cross-Site Scripting) — это критическая уязвимость, которая позволяет злоумышленникам внедрять вредоносный JavaScript код на веб-сайте. В Node.js приложении есть несколько слоев защиты.

1. Санитизация и эскейпинг входных данных

HTML-эскейпинг — самый важный способ защиты. Любые пользовательские данные, выводимые в HTML, должны быть экранированы:

const escape = require('html-escape');
const express = require('express');
const app = express();

app.get('/user/:name', (req, res) => {
  const safeName = escape(req.params.name);
  res.send(`Hello ${safeName}`);
});

Опции санитизации:

const DOMPurify = require('isomorphic-dompurify');

const userInput = '<img src=x onerror="alert("XSS")">';
const clean = DOMPurify.sanitize(userInput);

2. Content Security Policy (CSP)

CSP — это HTTP заголовок, который ограничивает источники скриптов:

const helmet = require('helmet');
const app = express();

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-inline'"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", "https:"],
  },
}));

Принципы CSP:

  • default-src 'self' — загружать ресурсы только с текущего домена
  • script-src 'none' — запретить все скрипты
  • script-src 'nonce-<random>' — разрешить только скрипты с правильным nonce

3. Использование шаблонизаторов с автоматическим эскейпингом

app.set('view engine', 'ejs');

app.get('/profile', (req, res) => {
  res.render('profile', {
    username: req.query.username,
  });
});

Рекомендуемые шаблонизаторы: EJS, Handlebars, Pug — все имеют автоматический эскейпинг.

4. Валидация и белые списки

const { body, validationResult } = require('express-validator');

app.post('/comment', 
  body('comment')
    .trim()
    .escape()
    .isLength({ min: 1, max: 500 })
    .matches(/^[a-zA-Z0-9\s.,!?-]+$/),
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    
    const comment = req.body.comment;
    res.json({ success: true });
  }
);

5. Заголовки безопасности с Helmet.js

const helmet = require('helmet');
const express = require('express');
const app = express();

app.use(helmet());

app.use(helmet.frameguard()); // X-Frame-Options: DENY
app.use(helmet.hsts()); // HTTP Strict-Transport-Security
app.use(helmet.noSniff()); // X-Content-Type-Options: nosniff
app.use(helmet.xssFilter()); // X-XSS-Protection: 1; mode=block

6. HTTPS и Secure Cookies

app.post('/login', (req, res) => {
  res.cookie('sessionToken', 'token-value', {
    httpOnly: true,
    secure: true,
    sameSite: 'Strict',
    maxAge: 3600000,
  });
  
  res.json({ success: true });
});

7. Полный пример защиты

const express = require('express');
const helmet = require('helmet');
const DOMPurify = require('isomorphic-dompurify');
const { body, validationResult } = require('express-validator');

const app = express();

app.use(helmet());
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'"],
  },
}));

app.use(express.json({ limit: '10kb' }));

app.post('/post', 
  body('title').trim().escape().isLength({ min: 1, max: 200 }),
  body('content').trim().escape().isLength({ min: 1, max: 5000 }),
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    
    const cleanTitle = DOMPurify.sanitize(req.body.title);
    const cleanContent = DOMPurify.sanitize(req.body.content);
    
    res.json({ success: true });
  }
);

app.listen(3000);

Чеклист защиты от XSS

  • Используй HTML-эскейпинг для всех пользовательских данных
  • Установи Content Security Policy (CSP) заголовки
  • Используй шаблонизаторы с автоматическим экранированием
  • Валидируй входные данные на стороне сервера
  • Применяй Helmet.js для установки заголовков безопасности
  • Используй httpOnly и secure флаги для cookies
  • Ограничь размер входящих данных
  • Регулярно обновляй зависимости

Рекомендуемые библиотеки

  • helmet — автоматическая установка заголовков безопасности
  • express-validator — валидация и санитизация входных данных
  • isomorphic-dompurify — универсальная санитизация HTML
  • html-escape — простое экранирование HTML
  • xss — специализированная библиотека защиты от XSS

Правильная защита от XSS требует многослойного подхода: валидация, санитизация, правильные заголовки и использование проверенных библиотек.