Проектування безпеки на рівні програми
Коли мова йде про розробку додатків, безпека — це як замикати двері на ніч: важливо, але часто про це згадують лише коли вже пізно. У Node.js, де швидкість і масштабованість займають важливе місце, уразливості, такі як SQL-ін'єкції, CSRF та XSS, можуть прокрастися, якщо не бути уважним. Цей посібник ознайомить вас з основними практиками, які допоможуть зберегти ваші додатки на Node.js в безпеці, з безліччю інструментів і порад для цього. 🚀
Частина 1: Запобігання уразливостям 🛡️
1. Захист від SQL-ін'єкцій 💉
SQL-ін'єкція — це як дати хакеру ключі від вашої бази даних. 🏦 Для захисту від неї:
Використовуйте параметризовані запити 🔑
Замість того, щоб додавати введення користувача безпосередньо в запити, завжди використовуйте параметризовані запити. Ось як це зробити за допомогою Knex.js:
const userId = req.body.userId;
const user = await knex('users').where('id', userId).first();
За допомогою Sequelize:
const user = await User.findOne({
where: { id: req.body.userId },
});
Ці бібліотеки автоматично екранізують введення користувача, що робить їх безпечними.
Уникайте сирих запитів ⚠️
Сирі SQL запити — це потужний, але ризикований інструмент. Якщо ви все ж змушені їх використовувати, обов'язково очищайте введення:
await knex.raw('SELECT * FROM users WHERE id = ?', [userId]);
2. Захист від XSS (міжсайтових скриптових атак) 🚫🖋️
XSS дозволяє зловмисникам вставляти шкідливі скрипти у ваш додаток. Для захисту:
- Очищення введення: Використовуйте бібліотеки, такі як DOMPurify для очищення на клієнтській стороні або sanitize-html на сервері.
- Екранізація виводів: Екрануйте динамічні дані у своїх шаблонах, використовуючи бібліотеки, як-от ejs:
<%= escape(user.name) %>
- Встановлення Content Security Policy (CSP): Обмежте джерела скриптів, які ваш додаток може виконувати:
Content-Security-Policy: script-src 'self'
3. Боротьба з CSRF (міжсайтовими підробками запитів) 🎭
CSRF маніпулює користувачем, змушуючи його виконувати непотрібні дії на вашому сайті. Для запобігання цьому:
- Використовуйте CSRF токени: Бібліотеки, як-от csurf, генерують токени для кожної сесії.
const csurf = require('csurf'); app.use(csurf());
- Перевіряйте заголовки Origin: Перевіряйте заголовки
Referer
іOrigin
для чутливих дій. - Встановлюйте cookies з параметром SameSite: Це запобігає відправці cookies при запитах з інших джерел:
res.cookie('sessionId', sessionId, { sameSite: 'strict' });
Частина 2: Управління секретами та чутливою інформацією 🔑
Секрети у вашій кодовій базі — це як залишати ключі від дому під килимком — зручно, але небезпечно. 🗝️ Ось як керувати ними безпечно:
1. Використовуйте змінні середовища за допомогою dotenv 🌱
Тримайте секрети подалі від вашого коду за допомогою dotenv:
- Встановіть dotenv:
npm install dotenv
- Додайте секрети до файлу
.env
:
DB_PASSWORD=supersecretpassword
- Завантажте їх у додатку:
require('dotenv').config(); const dbPassword = process.env.DB_PASSWORD;
2. Використовуйте AWS Secrets Manager або Vault ☁️
Для продакшн середовища зберігайте секрети в спеціалізованому сервісі, як-от AWS Secrets Manager:
const AWS = require('aws-sdk');
const client = new AWS.SecretsManager();
const secret = await client.getSecretValue({ SecretId: 'my-secret-id' }).promise();
console.log(JSON.parse(secret.SecretString));
3. Уникайте комітування секретів до Git 🛑
Використовуйте файл .gitignore
для виключення ваших .env
або секретних файлів:
.env
Також використовуйте інструменти, як-от git-secrets, для перевірки на наявність хардкодованих секретів у вашому репозиторії.
Частина 3: Реалізація безпечної аутентифікації 🔐
Аутентифікація — це передні двері вашого додатка, тому переконайтеся, що вони надійно замкнені! 🚪
1. OAuth2 🔑
OAuth2 — це золотий стандарт для безпечної аутентифікації на основі токенів.
Використовуйте бібліотеки, такі як passport:
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: '/auth/google/callback',
}, (accessToken, refreshToken, profile, done) => {
// Знайти або створити користувача
done(null, profile);
}));
2. JSON Web Tokens (JWT) 🛡️
JWT — це легковажні токени, ідеальні для безстанної аутентифікації. Ось приклад:
Підписання токену:
const jwt = require('jsonwebtoken');
const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { expiresIn: '1h' });
const decoded = jwt.verify(token, process.env.JWT_SECRET);
console.log(decoded.userId);
Перевірка токену:
3. OpenID Connect (OIDC) 🌍
OIDC побудований на OAuth2 і додає рівень ідентифікації. Сервіси, такі як Auth0 або Okta, спрощують реалізацію:
const { auth } = require('express-openid-connect');
app.use(auth({
issuerBaseURL: 'https://your-tenant.auth0.com',
clientID: process.env.CLIENT_ID,
secret: process.env.SECRET,
baseURL: 'http://localhost:3000',
}));
Бонусні поради ✨
- Завжди перевіряйте введення 🚦: Використовуйте бібліотеки, такі як Joi або express-validator, для перевірки введення користувачів.
- Тримайте залежності оновленими 🛠️: Використовуйте інструменти, такі як
npm audit
і Snyk, для перевірки вразливостей. - Включіть HTTPS 🌐: Завжди шифруйте зв'язок за допомогою TLS сертифікатів.
- Обмежуйте кількість запитів до API 🕒: Запобігайте атакам методом грубої сили, використовуючи бібліотеки, як-от express-rate-limit.
Висновок 🎉
Розробка з урахуванням безпеки в Node.js — це не просто бажана функціональність, а необхідність. Дотримуючись цих практик, ви зможете створювати надійні та безпечні додатки, які витримають виклики сучасної веб-розробки. Пам'ятайте:
- Не довіряйте введенню користувача. Перевіряйте все! 🙅♂️
- Тримайте секрети в таємниці. 🔒
- Безпечна аутентифікація — це ваш перший рівень захисту. 🛡️
Щасливого кодування та залишайтеся в безпеці! 🚀
Дякую, що є частиною спільноти
Перед тим, як піти:
- Обов'язково поставте лайк та підпишіться на автора ️👏️️
- Слідкуйте за нами: X | LinkedIn | YouTube | Newsletter | Podcast
- Перевірте CoFeed, розумний спосіб залишатися в курсі останніх новин у технологіях 🧪
- Розпочніть свій власний безкоштовний блог, що працює на штучному інтелекті на Differ 🚀
- Приєднуйтесь до нашої спільноти контент-креаторів на Discord 🧑🏻💻
- Для більшої кількості контенту відвідайте plainenglish.io + stackademic.com
Перекладено з: Secure Development Practices in Node.js 🔒