Introduction
La sécurité web est un domaine critique pour tout développeur. L'OWASP Top 10 liste les vulnérabilités les plus dangereuses et les plus répandues dans les applications web modernes.
⚠️ Important : Ces exemples sont fournis à des fins éducatives uniquement.
1. Injection (SQL, NoSQL, OS)
L'injection est la faille la plus courante et la plus dangereuse.
Exemple vulnérable
// ❌ DANGEREUX — injection SQL
const query = `SELECT * FROM users WHERE id = '${req.params.id}'`;
db.query(query);Contre-mesure
// ✅ Requête paramétrée
const query = 'SELECT * FROM users WHERE id = $1';
db.query(query, [req.params.id]);2. Broken Authentication
Les problèmes d'authentification permettent à des attaquants d'usurper des identités.
// ✅ Bonne pratique : hachage sécurisé des mots de passe
import { hash, verify } from 'argon2';
// À l'inscription
const hashedPassword = await hash(password, {
type: argon2.argon2id,
memoryCost: 65536,
timeCost: 3,
parallelism: 4,
});
// À la connexion
const isValid = await verify(hashedPassword, inputPassword);3. Cross-Site Scripting (XSS)
Le XSS permet d'injecter du code malveillant dans les pages web.
Types de XSS
graph LR
A[XSS] --> B[Reflected XSS]
A --> C[Stored XSS]
A --> D[DOM-based XSS]
B --> E[Vecteur: URL/paramètre]
C --> F[Vecteur: Base de données]
D --> G[Vecteur: DOM client]Contre-mesures
// ✅ Content Security Policy
const csp = [
"default-src 'self'",
`script-src 'self' 'nonce-${nonce}'`,
"style-src 'self' 'unsafe-inline'",
"frame-ancestors 'none'",
].join('; ');
res.setHeader('Content-Security-Policy', csp);4. Insecure Direct Object References (IDOR)
Un utilisateur accède à des ressources qui ne lui appartiennent pas.
// ❌ IDOR — accès sans vérification
app.get('/api/documents/:id', async (req, res) => {
const doc = await Document.findById(req.params.id);
res.json(doc); // N'importe qui peut accéder !
});
// ✅ Vérification des droits
app.get('/api/documents/:id', authenticate, async (req, res) => {
const doc = await Document.findOne({
_id: req.params.id,
userId: req.user.id, // Filtrage par utilisateur
});
if (!doc) return res.status(404).json({ error: 'Not found' });
res.json(doc);
});5. Security Misconfiguration
Les mauvaises configurations exposent des informations sensibles.
Headers de sécurité essentiels
| Header | Valeur recommandée | Protection |
|---|---|---|
X-Frame-Options | DENY | Clickjacking |
X-Content-Type-Options | nosniff | MIME sniffing |
Strict-Transport-Security | max-age=63072000; includeSubDomains | HTTPS forcé |
Referrer-Policy | strict-origin-when-cross-origin | Fuite de référent |
Permissions-Policy | camera=(), microphone=() | Accès aux APIs |
6. Sensitive Data Exposure
Les données sensibles doivent être protégées au repos et en transit.
// ✅ Ne jamais retourner des données sensibles
interface UserPublic {
id: string;
name: string;
email: string;
// Pas de password, token, etc.
}
function sanitizeUser(user: User): UserPublic {
const { password, resetToken, ...publicData } = user;
return publicData;
}7. Cycle de vie des dépendances
# Audit régulier
npm audit
# Mise à jour des packages
npx npm-check-updates -u
# Scan automatique en CI
# .github/workflows/security.ymlChecklist sécurité
Avant chaque déploiement :
Conclusion
La sécurité est un processus continu, pas un état. Adoptez une approche Security by Design :
- Réduire la surface d'attaque — désactiver ce qui n'est pas nécessaire
- Défense en profondeur — plusieurs couches de protection
- Principe du moindre privilège — accès minimal nécessaire
- Fail securely — en cas d'erreur, refuser plutôt qu'accorder