Node.jsМодуль 6: Безопасность
Защита от атак
XSS, CSRF, SQL Injection, Rate Limiting, CORS
Цель урока
В этом уроке ты научишься:
- Защищаться от основных атак
- Настраивать CORS
- Ограничивать количество запросов
Helmet
Защита HTTP заголовков.
npm install helmetconst helmet = require('helmet');
app.use(helmet());
// Или с настройками
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"]
}
}
}));XSS (Cross-Site Scripting)
Проблема
// Опасно: вставка пользовательского ввода
res.send(`<h1>Привет, ${req.query.name}</h1>`);
// ?name=<script>alert('XSS')</script>Защита
npm install xssconst xss = require('xss');
// Очистка ввода
const safeName = xss(req.query.name);
res.send(`<h1>Привет, ${safeName}</h1>`);
// Или middleware
function sanitize(req, res, next) {
if (req.body) {
for (const key in req.body) {
if (typeof req.body[key] === 'string') {
req.body[key] = xss(req.body[key]);
}
}
}
next();
}CSRF (Cross-Site Request Forgery)
Установка
npm install csurfНастройка
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
app.use(cookieParser());
app.use(csrfProtection);
// Передаём токен клиенту
app.get('/form', (req, res) => {
res.json({ csrfToken: req.csrfToken() });
});
// Клиент должен отправить токен в заголовке
// X-CSRF-Token: <token>SQL/NoSQL Injection
Проблема
// Опасно!
const user = await User.findOne({ email: req.body.email });
// email: { "$gt": "" } — вернёт первого пользователяЗащита
// Валидация типов
const { email } = req.body;
if (typeof email !== 'string') {
return res.status(400).json({ error: 'Invalid email' });
}
// Использование схем валидации (Joi, Zod)
const schema = Joi.object({
email: Joi.string().email().required()
});
// Mongoose sanitize
npm install express-mongo-sanitizeconst mongoSanitize = require('express-mongo-sanitize');
app.use(mongoSanitize());
// Удаляет $ и . из req.body, req.query, req.paramsRate Limiting
npm install express-rate-limitconst rateLimit = require('express-rate-limit');
// Общий лимит
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 минут
max: 100, // 100 запросов
message: { error: 'Too many requests' }
});
app.use(limiter);
// Лимит для логина
const loginLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 час
max: 5, // 5 попыток
message: { error: 'Too many login attempts' }
});
app.post('/login', loginLimiter, loginHandler);CORS
npm install corsconst cors = require('cors');
// Разрешить все origins (не для production!)
app.use(cors());
// С настройками
app.use(cors({
origin: ['http://localhost:3000', 'https://myapp.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true // Для cookies
}));
// Динамический origin
app.use(cors({
origin: (origin, callback) => {
const allowedOrigins = ['http://localhost:3000'];
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
}));Дополнительные меры
HPP (HTTP Parameter Pollution)
npm install hppconst hpp = require('hpp');
app.use(hpp());
// ?sort=name&sort=email → ?sort=email (последний)Compression
npm install compressionconst compression = require('compression');
app.use(compression());Чеклист безопасности
- Используй HTTPS
- Включи Helmet
- Настрой CORS
- Добавь Rate Limiting
- Валидируй все входные данные
- Используй параметризованные запросы
- Храни секреты в переменных окружения
- Логируй подозрительную активность
- Регулярно обновляй зависимости
Практика
Задание: Безопасный сервер
Задача: Настрой базовую безопасность.
Решение:
const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
const mongoSanitize = require('express-mongo-sanitize');
const app = express();
// Security middleware
app.use(helmet());
app.use(cors({ origin: process.env.FRONTEND_URL }));
app.use(mongoSanitize());
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
app.use(express.json({ limit: '10kb' }));Проверь себя
- Что делает Helmet?
- Как защититься от XSS?
- Зачем нужен Rate Limiting?