MFormations
Modern Backend Engineering

Chapitre 9

Chapitre 09 — Sécurité Backend

Chapitre 09 — Sécurité Backend

Cours — Sécurité Backend

1. OWASP Top 10 (2021)

1.1 Broken Access Control

L'accès non contrôlé aux ressources représente la vulnérabilité la plus critique.

  • IDOR (Insecure Direct Object References)
  • Missing function-level access control
  • Path traversal

Exemple d'attaque IDOR :

GET /api/users/12345/orders → récupération des commandes d'un autre utilisateur

Mitigation : Toujours vérifier les droits d'accès côté serveur. Ne jamais faire confiance à l'input client.

1.2 Cryptographic Failures

Données sensibles mal protégées (anciennement "Sensitive Data Exposure").

  • Mots de passe stockés en clair
  • Chiffrement faible (MD5, SHA1 pour les passwords)
  • Certificats TLS expirés

Bonnes pratiques :

  • Utiliser bcrypt, Argon2 ou scrypt pour les mots de passe
  • Chiffrer les données au repos (AES-256-GCM)
  • Forcer TLS 1.3 en transit

1.3 Injection

SQL, NoSQL, OS command, LDAP injection.

SQL Injection classique :

SELECT * FROM users WHERE email = 'admin@example.com' OR '1'='1'

Mitigation :

  • Prepared statements (parametrized queries)
  • ORM avec échappement automatique
  • Validation stricte des entrées

1.4 Insecure Design

Manque de sécurité dans la conception.

  • Rate limiting absent
  • Trust boundaries mal définies
  • Fail-open vs fail-secure

1.5 Security Misconfiguration

  • Comptes par défaut (admin/admin)
  • Headers de sécurité manquants
  • Stack traces exposées en production
  • Cloud storage publiquement accessible

1.6 Vulnerable and Outdated Components

  • Dépendances avec CVE connues
  • Versionning : utiliser npm audit, snyk, dependabot

1.7 Authentication and Identification Failures

  • Session fixation
  • Credential stuffing
  • MFA absent
  • Weak password policy

1.8 Software and Data Integrity Failures

  • Supply chain attacks
  • Unsigned updates
  • CI/CD pipeline security

1.9 Security Logging and Monitoring Failures

  • Logs insuffisants pour forensic
  • Absence d'alerting
  • Monitoring des accès non autorisés

1.10 Server-Side Request Forgery (SSRF)

  • Attaquant force le serveur à faire des requêtes vers des ressources internes
  • Mitigation : allowlist de domaines, validation d'URL

2. JWT (JSON Web Tokens)

Structure

header.payload.signature

Header :

{"alg": "HS256", "typ": "JWT"}

Payload :

{
  "sub": "user123",
  "role": "admin",
  "iat": 1516239022,
  "exp": 1516242622
}

Best Practices

  • Utiliser une clé secrète forte (HS256) ou RSA/ECDSA (RS256, ES256)
  • Expiration courte (15-60 minutes)
  • Refresh token avec rotation
  • Blacklist des tokens révoqués
  • Ne jamais stocker de secrets dans le payload

Implémentation Node.js

const jwt = require('jsonwebtoken');
const token = jwt.sign({ userId: 1, role: 'admin' }, SECRET, { expiresIn: '1h' });
jwt.verify(token, SECRET, (err, decoded) => { /* ... */ });

3. OAuth2 & OpenID Connect

OAuth2 Grant Types

Grant TypeUsage
Authorization CodeWeb apps (recommandé)
PKCEMobile / SPA (sécurisé)
Client CredentialsService-to-service
ImplicitDéprécié (ne plus utiliser)

OpenID Connect

Extension d'OAuth2 pour l'authentification.

  • Ajoute id_token (JWT)
  • Endpoint /.well-known/openid-configuration
  • Claims : sub, name, email, email_verified

Architecture

Client → Authorization Server → Resource Server
  1. Demande auth
  2. Code d'autorisation
  3. Échange contre access_token + id_token
  4. Accès API avec access_token

4. RBAC (Role-Based Access Control)

Modèle

User → Role → Permission → Resource

Exemple de permissions

const permissions = {
  admin:   ['read', 'write', 'delete', 'manage_users'],
  editor:  ['read', 'write'],
  viewer:  ['read']
};

function authorize(user, action) {
  return permissions[user.role]?.includes(action);
}

ABAC (Attribute-Based Access Control)

Plus fin : basé sur attributs utilisateur, ressource, environnement.

{
  "effect": "deny",
  "condition": {
    "user.department": "!= resource.department",
    "user.clearance": "< resource.classification"
  }
}

5. Chiffrement

TLS (Transport Layer Security)

  • TLS 1.3 recommandé
  • HSTS header : Strict-Transport-Security: max-age=31536000
  • Certificats Let's Encrypt (gratuits)

AES (Advanced Encryption Standard)

const crypto = require('crypto');
const key = crypto.randomBytes(32); // AES-256
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

bcrypt

const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12); // salt rounds = 12
const match = await bcrypt.compare(password, hash);

Argon2 (recommandé pour 2026)

const argon2 = require('argon2');
const hash = await argon2.hash(password, { type: argon2.argon2id });

6. Content Security Policy (CSP)

En-tête HTTP qui prévient XSS et data injection.

Content-Security-Policy: default-src 'self';
  script-src 'self' https://trusted-cdn.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data:;
  object-src 'none';
  frame-ancestors 'none';

Directives clés

  • default-src : fallback pour toutes les resources
  • script-src : sources autorisées pour JS
  • style-src : sources autorisées pour CSS
  • img-src : sources autorisées pour images
  • connect-src : URLs pour fetch/XHR
  • frame-ancestors : prévention clickjacking
  • report-uri / report-to : endpoint de rapport

7. SQL Injection — Prévention

Toujours utiliser des requêtes paramétrées

Mauvais (vulnérable) :

const query = `SELECT * FROM users WHERE email = '${email}'`;

Bon (paramétré) :

db.query('SELECT * FROM users WHERE email = $1', [email]);

ORM sécurisé (Prisma, TypeORM, Sequelize)

Les ORMs modernes échappent automatiquement les paramètres. Attention aux raw queries.


8. XSS — Types et Défenses

TypeDescription
Reflected XSSPayload dans URL/request, exécuté immédiatement
Stored XSSPayload stocké en BDD, servi à chaque visiteur
DOM-based XSSVulnérabilité côté client via JavaScript

Défenses

  1. Output encoding : échapper < > & " '&lt; &gt; &amp; &quot; &#x27;
  2. CSP : restreindre les sources de scripts
  3. HttpOnly cookies : empêcher l'accès JS aux cookies
  4. Sanitization : DOMPurify, sanitize-html

9. CSRF (Cross-Site Request Forgery)

L'attaquant force un utilisateur authentifié à exécuter des actions non souhaitées.

Mitigation

  1. CSRF Token : token unique lié à la session
  2. SameSite Cookie : SameSite=Strict ou SameSite=Lax
  3. Custom headers : vérifier un header personnalisé (ex: X-Requested-With)
  4. Origin/Referer validation
// Express avec csurf
app.use(csurf({ cookie: true }));
app.get('/form', (req, res) => {
  res.render('form', { csrfToken: req.csrfToken() });
});

10. Rate Limiting et API Security

Rate Limiting

const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests
  standardHeaders: true,
  message: { error: 'Too many requests' }
});
app.use('/api/', limiter);

Stratégies avancées

  • Token bucket : AWS, Stripe
  • Leaky bucket : nginx rate limiting
  • Sliding window : plus précis que fixed window
  • Per-user vs per-IP : combiner les deux

API Security Checklist

  • HTTPS only (HSTS)
  • Authentication & Authorization
  • Rate limiting (global + per-endpoint)
  • Input validation (JSON Schema, Zod)
  • Security headers (CSP, X-Frame-Options, X-Content-Type-Options)
  • CORS configuré précisément
  • API keys rotation
  • Audit logging
  • Request size limitation
  • SQL/NoSQL injection prevention

11. Security Headers

Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()

Outils de vérification