Практики безпечної розробки в Node.js 🔒

pic

Проектування безпеки на рівні програми

Коли мова йде про розробку додатків, безпека — це як замикати двері на ніч: важливо, але часто про це згадують лише коли вже пізно. У 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:

  1. Встановіть dotenv:
npm install dotenv
  1. Додайте секрети до файлу .env:
DB_PASSWORD=supersecretpassword
  1. Завантажте їх у додатку:
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 — це не просто бажана функціональність, а необхідність. Дотримуючись цих практик, ви зможете створювати надійні та безпечні додатки, які витримають виклики сучасної веб-розробки. Пам'ятайте:

  • Не довіряйте введенню користувача. Перевіряйте все! 🙅‍♂️
  • Тримайте секрети в таємниці. 🔒
  • Безпечна аутентифікація — це ваш перший рівень захисту. 🛡️

Щасливого кодування та залишайтеся в безпеці! 🚀

Дякую, що є частиною спільноти

Перед тим, як піти:

Перекладено з: Secure Development Practices in Node.js 🔒

Leave a Reply

Your email address will not be published. Required fields are marked *