← Назад к вопросам
Какие знаешь практики обеспечения безопасности на проекте?
2.3 Middle🔥 121 комментариев
#Безопасность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Практики обеспечения безопасности в проектах Node.js
Безопасность — это многоуровневый процесс. Рассмотрю основные практики на разных уровнях.
1. Аутентификация и авторизация
JWT токены с безопасным хранением:
const jwt = require('jsonwebtoken');
function generateAccessToken(userId) {
return jwt.sign(
{ userId, role: 'user' },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
}
function generateRefreshToken(userId) {
return jwt.sign(
{ userId, tokenVersion: 1 },
process.env.REFRESH_SECRET,
{ expiresIn: '7d' }
);
}
res.cookie('refreshToken', token, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 7 * 24 * 60 * 60 * 1000
});
Проверка прав доступа:
function authorize(...requiredRoles) {
return (req, res, next) => {
const user = req.user;
if (!user || !requiredRoles.includes(user.role)) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
}
app.delete('/api/users/:id', authenticate, authorize('admin'), async (req, res) => {
// Только админы могут удалять
});
2. Защита от SQL инъекций
Параметризованные запросы:
const query = 'SELECT * FROM users WHERE id = $1';
await pool.query(query, [id]);
ORM с автоматической защитой:
const user = await User.findOne({ where: { id } });
await pool.query(
'INSERT INTO users (name, email) VALUES ($1, $2)',
[name, email]
);
3. Защита от XSS
Санитизация пользовательского ввода:
const DOMPurify = require('isomorphic-dompurify');
const userInput = req.body.comment;
const clean = DOMPurify.sanitize(userInput);
await db.saveComment(clean);
Content Security Policy:
app.use((req, res, next) => {
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; script-src 'self'"
);
next();
});
4. Защита от CSRF
CSRF tokens:
const csrf = require('csurf');
app.use(csrf({ cookie: true }));
app.post('/api/update', csrf(), (req, res) => {
res.json({ success: true });
});
SameSite Cookies:
res.cookie('sessionId', token, {
sameSite: 'strict',
secure: true,
httpOnly: true
});
5. Защита от Brute Force
Rate limiting:
const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
message: 'Слишком много попыток входа'
});
app.post('/api/login', loginLimiter, async (req, res) => {
// Обработка логина
});
Экспоненциальная задержка:
async function attemptLogin(email, password) {
const attempts = await db.getFailedAttempts(email);
if (attempts >= 3) {
const delay = Math.pow(2, Math.min(attempts - 3, 5));
throw new Error(`Account locked for ${delay} seconds`);
}
const user = await authenticateUser(email, password);
if (!user) {
await db.recordFailedAttempt(email);
throw new Error('Invalid credentials');
}
await db.clearFailedAttempts(email);
return user;
}
6. Управление секретами
Environment variables:
const secret = process.env.JWT_SECRET;
if (!secret) {
throw new Error('JWT_SECRET not set');
}
Secrets Manager:
const SecretsManager = require('aws-sdk/clients/secretsmanager');
async function getSecret(secretName) {
const client = new SecretsManager({ region: 'us-east-1' });
const data = await client.getSecretValue({ SecretId: secretName }).promise();
return JSON.parse(data.SecretString);
}
7. Валидация данных
Schema validation:
const Joi = require('joi');
const userSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).required(),
age: Joi.number().integer().min(18).max(120)
});
app.post('/api/register', (req, res) => {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
});
8. Логирование и мониторинг
Безопасное логирование:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' })
]
});
logger.info('User login', { userId, email, ip: req.ip });
logger.error('Login failed', { email, reason: 'invalid' });
Мониторинг anomalies:
async function monitorLogin(email, ip) {
const recentLogins = await db.getRecentLogins(email, '24h');
const ips = new Set(recentLogins.map(l => l.ip));
if (recentLogins.length > 10 || ips.size > 5) {
await sendSecurityAlert(email, 'Unusual login activity');
}
}
9. HTTPS и TLS
Обязательный HTTPS:
app.use((req, res, next) => {
if (!req.secure && process.env.NODE_ENV === 'production') {
return res.redirect(`https://${req.headers.host}${req.url}`);
}
next();
});
res.setHeader('Strict-Transport-Security', 'max-age=31536000');
10. Dependency management
Проверяем и обновляем:
npm audit
npm update
npm ci
Чеклист безопасности
- JWT с коротким сроком действия
- Refresh tokens в HttpOnly cookies
- Параметризованные SQL запросы
- Санитизация пользовательского ввода
- CSRF protection включена
- Rate limiting на критичных операциях
- Секреты в environment variables
- HTTPS в production
- CSP заголовки установлены
- Логирование без чувствительных данных
- Регулярные обновления зависимостей
- Двухфакторная аутентификация для админов
Безопасность — это постоянный процесс контроля и улучшения, а не одноразовая настройка.