Які основні практики безпеки в Node.js?
Найкращі практики безпеки Node.js
Безпека є критично важливою в будь-якому бекенд-додатку. Node.js має специфічні вектори атак, які кожен розробник повинен розуміти та захищати.
1. Запобігання атакам ін'єкцій
SQL-ін'єкція
js
// ❌ Вразливо — конкатенація рядків
const query = `SELECT * FROM users WHERE id = '${req.params.id}'`;
// ✅ Безпечно — параметризовані запити
const result = await db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);NoSQL-ін'єкція (MongoDB)
js
// ❌ Вразливо — вхідні дані користувача можуть бути об'єктом
db.users.find({ username: req.body.username, password: req.body.password });
// Зловмисник надсилає: { "password": { "$gt": "" } }
// ✅ Безпечно — перевіряйте та очищайте вхідні дані
const username = String(req.body.username);
const password = String(req.body.password);
db.users.find({ username, password: hashPassword(password) });Ін'єкція команд
js
// ❌ Вразливо
const { exec } = require('child_process');
exec(`ls ${req.query.dir}`); // dir = "; rm -rf /"
// ✅ Безпечно — використовуйте execFile з масивом аргументів
const { execFile } = require('child_process');
execFile('ls', [req.query.dir]);2. Валідація вводу
Завжди перевіряйте та очищайте вхідні дані користувача:
js
const Joi = require('joi');
const schema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).max(128).required(),
age: Joi.number().integer().min(18).max(120)
});
const { error, value } = schema.validate(req.body);
if (error) return res.status(400).json({ error: error.details });3. Аутентифікація та авторизація
| Практика | Реалізація |
|---|---|
| Хешування паролів | bcrypt з кількістю раундів солі ≥ 12 |
| Обережне використання JWT | Короткий термін дії, httpOnly куки, токени оновлення |
| Лімітування запитів на вхід | Запобігання брутфорсу (express-rate-limit) |
| Використання HTTPS | Завжди в продуктивному середовищі |
js
const bcrypt = require('bcrypt');
// Хешування
const hash = await bcrypt.hash(password, 12);
// Перевірка
const isValid = await bcrypt.compare(password, hash);4. HTTP заголовки безпеки
Використовуйте helmet для налаштування заголовків безпеки:
js
const helmet = require('helmet');
app.use(helmet());
// Встановлює заголовки, такі як:
// X-Content-Type-Options: nosniff
// X-Frame-Options: DENY
// Strict-Transport-Security: max-age=31536000
// Content-Security-Policy: default-src 'self'5. Безпека залежностей
bash
# Перевірка на відомі вразливості
npm audit
# Автоматичне виправлення, де це можливо
npm audit fix
# Використовуйте Snyk для глибшого аналізу
npx snyk test6. Запобігання атакам відмови в обслуговуванні (DoS)
js
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 хвилин
max: 100, // обмежити кожну IP-адресу до 100 запитів за windowMs
message: 'Занадто багато запитів'
});
app.use('/api/', limiter);Захист від ReDoS (DoS на основі регулярних виразів):
js
// ❌ Вразливий регулярний вираз — катастрофічне зворотне відстеження
const regex = /^(a+)+$/;
regex.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaX'); // Зависає!
// ✅ Безпечно — використовуйте safe-regex або re2
const RE2 = require('re2');
const regex = new RE2('^(a+)+$');7. Безпечні змінні середовища
js
// ❌ Ніколи не хардкодьте секрети
const secret = 'my-secret-key';
// ✅ Використовуйте змінні середовища
const secret = process.env.JWT_SECRET;
// ✅ Перевірка під час запуску
if (!process.env.JWT_SECRET) {
throw new Error('JWT_SECRET є обов\'язковим');
}Контрольний список безпеки
| Категорія | Дія |
|---|---|
| Вхідні дані | Перевіряйте всі вхідні дані користувача (Joi, class-validator) |
| SQL/NoSQL | Використовуйте параметризовані запити |
| Аутентифікація | Хешуйте паролі з bcrypt, правильно використовуйте JWT |
| Заголовки | Використовуйте middleware helmet |
| HTTPS | Забезпечте TLS у продуктивному середовищі |
| Залежності | Регулярно запускайте npm audit |
| Лімітування запитів | Захистіть кінцеві точки від зловживань |
| Секрети | Використовуйте змінні середовища, ніколи не комітіть у git |
| Логування | Логуйте події безпеки, ніколи не логуйте секрети |
| CORS | Налаштуйте суворі політики походження |
Пам'ятайте: Безпека — це не функція, яку ви додаєте один раз — це спосіб мислення. Перевіряйте вхідні дані, очищайте вихідні, використовуйте принцип найменших привілеїв, підтримуйте залежності в актуальному стані та контролюйте аномалії.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.