Articlepar DevBlog

Sécurité Web : Les 10 failles OWASP à connaître

Tour d'horizon des 10 vulnérabilités web les plus critiques selon OWASP, avec des exemples concrets et les contre-mesures à implémenter dans vos applications.

  • #securite
  • #owasp
  • #web
  • #best-practices

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

javascript
// ❌ DANGEREUX — injection SQL
const query = `SELECT * FROM users WHERE id = '${req.params.id}'`;
db.query(query);

Contre-mesure

javascript
// ✅ 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.

typescript
// ✅ 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

typescript
// ✅ 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.

typescript
// ❌ 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

HeaderValeur recommandéeProtection
X-Frame-OptionsDENYClickjacking
X-Content-Type-OptionsnosniffMIME sniffing
Strict-Transport-Securitymax-age=63072000; includeSubDomainsHTTPS forcé
Referrer-Policystrict-origin-when-cross-originFuite de référent
Permissions-Policycamera=(), microphone=()Accès aux APIs

6. Sensitive Data Exposure

Les données sensibles doivent être protégées au repos et en transit.

typescript
// ✅ 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

bash
# Audit régulier
npm audit

# Mise à jour des packages
npx npm-check-updates -u

# Scan automatique en CI
# .github/workflows/security.yml

Checklist sécurité

Avant chaque déploiement :

Conclusion

La sécurité est un processus continu, pas un état. Adoptez une approche Security by Design :

  1. Réduire la surface d'attaque — désactiver ce qui n'est pas nécessaire
  2. Défense en profondeur — plusieurs couches de protection
  3. Principe du moindre privilège — accès minimal nécessaire
  4. Fail securely — en cas d'erreur, refuser plutôt qu'accorder