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 Type | Usage |
|---|---|
| Authorization Code | Web apps (recommandé) |
| PKCE | Mobile / SPA (sécurisé) |
| Client Credentials | Service-to-service |
| Implicit | Dé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 resourcesscript-src: sources autorisées pour JSstyle-src: sources autorisées pour CSSimg-src: sources autorisées pour imagesconnect-src: URLs pour fetch/XHRframe-ancestors: prévention clickjackingreport-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
| Type | Description |
|---|---|
| Reflected XSS | Payload dans URL/request, exécuté immédiatement |
| Stored XSS | Payload stocké en BDD, servi à chaque visiteur |
| DOM-based XSS | Vulnérabilité côté client via JavaScript |
Défenses
- Output encoding : échapper
< > & " '→< > & " ' - CSP : restreindre les sources de scripts
- HttpOnly cookies : empêcher l'accès JS aux cookies
- Sanitization :
DOMPurify,sanitize-html
9. CSRF (Cross-Site Request Forgery)
L'attaquant force un utilisateur authentifié à exécuter des actions non souhaitées.
Mitigation
- CSRF Token : token unique lié à la session
- SameSite Cookie :
SameSite=StrictouSameSite=Lax - Custom headers : vérifier un header personnalisé (ex:
X-Requested-With) - 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
- securityheaders.com
- Mozilla Observatory
curl -I https://votresite.com