Retour au blog
Sécurité Web 5 Feb 2026 · 25 min de lecture

OWASP Top 10 2025 : Risques critiques pour les applications web

H

Hakobjan Dev Team

Ingénieurs Sécurité & Logiciels

Le Top 10 OWASP est la liste de référence des risques de sécurité pour les applications web. L'édition 2025 apporte des changements importants : le broken access control reste #1, mais la SSRF et les risques de supply chain logicielle ont considérablement augmenté. Dans cet article complet, nous couvrons les dix catégories avec des exemples pratiques et des solutions.



A01 : Broken Access Control

Le Broken Access Control est la vulnérabilité la plus courante depuis des années. Cela revient à ne pas imposer que les utilisateurs ne peuvent faire que ce pour quoi ils sont autorisés. Pensez aux IDOR, l'escalade de privilèges et le contournement des contrôles d'accès.

La solution commence par un framework d'autorisation robuste : utilisez RBAC/ABAC, validez chaque requête côté serveur et ne vous fiez jamais aux seules vérifications côté client. Deny by default : si un utilisateur n'a pas de permission explicite, l'accès est refusé.

javascript
// Exemple : vulnérabilité IDOR
// FAUX - l'utilisateur peut interroger n'importe quelle commande
app.get('/api/orders/:id', auth, async (req, res) => {
  const order = await Order.findById(req.params.id);
  res.json(order); // Pas de vérification !
});

// CORRECT - ajouter une vérification d'autorisation
app.get('/api/orders/:id', auth, async (req, res) => {
  const order = await Order.findOne({
    _id: req.params.id,
    userId: req.user.id
  });
  if (!order) return res.status(404).json({ error: 'Non trouvé' });
  res.json(order);
});

A02 : Cryptographic Failures

Les Cryptographic Failures (anciennement "Sensitive Data Exposure") concernent l'échec de la protection des données en transit et au repos. Pensez aux mots de passe stockés en clair, à l'utilisation d'algorithmes obsolètes comme MD5 ou SHA1, à l'absence de TLS ou aux clés de chiffrement codées en dur dans le code source.

Utilisez toujours des algorithmes forts : bcrypt ou Argon2 pour les mots de passe, AES-256-GCM pour le chiffrement, TLS 1.3 pour les données en transit. Ne stockez jamais de données sensibles inutilement.

javascript
// FAUX - stocker le mot de passe avec MD5
const hash = crypto.createHash('md5').update(password).digest('hex');

// CORRECT - utiliser bcrypt avec salt rounds
const bcrypt = require('bcrypt');
const saltRounds = 12;
const hash = await bcrypt.hash(password, saltRounds);

// Vérification
const isValid = await bcrypt.compare(inputPassword, storedHash);

A03 : Injection

Les attaques par injection se produisent quand des données non fiables sont envoyées à un interpréteur dans le cadre d'une commande ou requête. L'injection SQL est la plus connue, mais l'injection NoSQL, OS command et LDAP entrent aussi dans cette catégorie.

Utilisez toujours des requêtes paramétrées ou des instructions préparées. Utilisez des ORM qui appliquent automatiquement l'échappement. Validez et assainissez toutes les entrées côté serveur.

javascript
// FAUX - vulnérabilité injection SQL
const query = `SELECT * FROM users WHERE id = ${req.params.id}`;
db.query(query);

// CORRECT - requête paramétrée
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [req.params.id]);

// Exemple ORM (Sequelize)
const user = await User.findOne({
  where: { id: req.params.id }
});

A04 : Insecure Design

L'Insecure Design est un concept large pointant vers des défauts de conception fondamentaux. La différence avec les bugs d'implémentation est importante : une architecture non sécurisée parfaitement implémentée reste non sécurisée. Pensez à un flux de réinitialisation de mot de passe utilisant des questions de sécurité, ou une app e-commerce sans rate limiting sur les codes promo.

La solution : utilisez le threat modeling tôt dans le processus de développement. Implémentez des design patterns sécurisés comme la défense en profondeur, le moindre privilège et les valeurs par défaut sûres.

javascript
// FAUX - pas de rate limiting sur la réinitialisation
app.post('/api/reset-password', async (req, res) => {
  const user = await User.findByEmail(req.body.email);
  if (user) sendResetEmail(user); // Pas de limite !
  res.json({ message: 'Vérifiez votre email' });
});

// CORRECT - rate limiting + verrouillage de compte
const rateLimit = require('express-rate-limit');
const resetLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 3,
  message: 'Trop de requêtes, réessayez plus tard'
});
app.post('/api/reset-password', resetLimiter, async (req, res) => {
  // ... implémentation sécurisée
});

A05 : Security Misconfiguration

La Security Misconfiguration est le problème le plus répandu. Elle englobe le manque de durcissement, les fonctionnalités inutiles activées, les comptes et mots de passe par défaut, les messages d'erreur trop informatifs et les en-têtes HTTP de sécurité mal configurés.

Automatisez votre configuration serveur avec l'Infrastructure as Code. Supprimez les fonctionnalités, ports et services inutiles. Implémentez les en-têtes de sécurité (CSP, HSTS, X-Frame-Options).

yaml
# Configuration des en-têtes de sécurité Nginx
server {
  # Strict Transport Security
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

  # Content Security Policy
  add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;

  # Prévenir le clickjacking
  add_header X-Frame-Options "SAMEORIGIN" always;

  # Prévenir le MIME type sniffing
  add_header X-Content-Type-Options "nosniff" always;

  # Masquer la version du serveur
  server_tokens off;
}

A06 : Vulnerable & Outdated Components

Les applications modernes contiennent des dizaines à des centaines de dépendances. Chacune peut contenir des vulnérabilités. En 2024, plus de 29 000 nouveaux CVE ont été publiés. Les suivre sans outillage est impossible.

Utilisez des outils SCA comme Snyk, npm audit ou Dependabot. Supprimez les dépendances inutilisées. Fixez vos versions et mettez à jour régulièrement. Surveillez les nouveaux CVE et ayez une stratégie de patch prête.

bash
# Vérifier les vulnérabilités dans votre projet
npm audit

# Corriger automatiquement les packages vulnérables
npm audit fix

# Scan Snyk pour une analyse approfondie
npx snyk test

# Afficher les packages obsolètes
npm outdated

# Config Dependabot (.github/dependabot.yml)
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"

A07 : Identification & Authentication Failures

Les Authentication Failures incluent les attaques par force brute, le credential stuffing, les politiques de mots de passe faibles, l'absence d'authentification multifacteur (MFA) et la mauvaise gestion des sessions. La fixation de session, le détournement de session et la non-invalidation des sessions à la déconnexion sont des erreurs courantes.

Implémentez le MFA, utilisez des politiques de mots de passe fortes et des frameworks de gestion de sessions éprouvés. Limitez les tentatives de connexion et implémentez des mécanismes de verrouillage de compte.

javascript
// Login avec protection brute-force
const loginAttempts = new Map();

app.post('/api/login', async (req, res) => {
  const { email, password } = req.body;
  const attempts = loginAttempts.get(email) || { count: 0, lockUntil: 0 };

  if (attempts.lockUntil > Date.now()) {
    return res.status(429).json({ error: 'Compte temporairement verrouillé' });
  }

  const user = await User.findByEmail(email);
  const valid = user && await bcrypt.compare(password, user.password);

  if (!valid) {
    attempts.count++;
    if (attempts.count >= 5) {
      attempts.lockUntil = Date.now() + 15 * 60 * 1000;
    }
    loginAttempts.set(email, attempts);
    return res.status(401).json({ error: 'Identifiants invalides' });
  }

  loginAttempts.delete(email);
  const token = generateJWT(user);
  res.json({ token });
});

A08 : Software & Data Integrity Failures

Cette catégorie se concentre sur les hypothèses concernant les mises à jour logicielles, les données critiques et les pipelines CI/CD sans vérification d'intégrité. Pensez à l'attaque SolarWinds : les attaquants ont compromis le système de build et ajouté des malwares aux mises à jour légitimes installées par des milliers d'organisations.

Utilisez le Subresource Integrity (SRI) pour les scripts externes. Signez numériquement les releases. Sécurisez votre pipeline CI/CD avec du code signing et des environnements de build séparés.

javascript
// Subresource Integrity (SRI) pour scripts externes
<script
  src="https://cdn.example.com/lib.min.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxAh6VgnSY"
  crossorigin="anonymous">
</script>

// Vérification du lock file dans le pipeline CI
// Toujours committer package-lock.json ou yarn.lock
// Utiliser npm ci au lieu de npm install en CI
npm ci --ignore-scripts

// Vérifier l'intégrité des packages
npm audit signatures

A09 : Security Logging & Monitoring Failures

Sans journalisation et surveillance adéquates, les attaques ne sont découvertes que trop tard. Les études montrent que le temps moyen de détection d'une brèche est de plus de 200 jours. Beaucoup d'organisations ne journalisent pas suffisamment ou ne surveillent pas activement leurs logs.

Journalisez tous les événements d'authentification, les échecs de contrôle d'accès et les erreurs côté serveur. Centralisez les logs avec des outils comme ELK Stack ou Grafana Loki. Configurez des alertes pour les schémas suspects.

javascript
// Journalisation de sécurité structurée avec Winston
const winston = require('winston');

const securityLogger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  defaultMeta: { service: 'auth-service' },
  transports: [
    new winston.transports.File({ filename: 'security.log' })
  ]
});

// Journaliser les tentatives de connexion échouées
app.post('/api/login', async (req, res) => {
  const { email } = req.body;
  const success = await authenticate(email, req.body.password);

  securityLogger.info({
    event: success ? 'LOGIN_SUCCESS' : 'LOGIN_FAILURE',
    email,
    ip: req.ip,
    userAgent: req.headers['user-agent'],
    timestamp: new Date().toISOString()
  });
});

A10 : Server-Side Request Forgery (SSRF)

Les attaques SSRF trompent le serveur pour qu'il fasse des requêtes vers des emplacements non prévus. Dans les environnements cloud, c'est particulièrement dangereux : les attaquants peuvent accéder au endpoint de métadonnées (ex. http://169.254.169.254 sur AWS) pour voler des credentials. La brèche Capital One de 2019 était une attaque SSRF qui a fuité 100 millions d'enregistrements.

Validez et assainissez toutes les URLs fournies par l'utilisateur. Utilisez une allowlist de domaines autorisés. Bloquez les requêtes vers les plages IP privées et les endpoints de métadonnées cloud.

javascript
// FAUX - URL utilisateur sans validation
app.post('/api/fetch-url', async (req, res) => {
  const response = await fetch(req.body.url); // SSRF !
  res.json(await response.json());
});

// CORRECT - validation d'URL avec allowlist
const allowedDomains = ['api.example.com', 'cdn.example.com'];

function isAllowedUrl(urlString) {
  try {
    const url = new URL(urlString);
    if (!['http:', 'https:'].includes(url.protocol)) return false;
    if (!allowedDomains.includes(url.hostname)) return false;
    const ip = url.hostname;
    if (ip.startsWith('10.') || ip.startsWith('192.168.') ||
        ip.startsWith('169.254.') || ip === 'localhost') return false;
    return true;
  } catch { return false; }
}

app.post('/api/fetch-url', async (req, res) => {
  if (!isAllowedUrl(req.body.url)) {
    return res.status(400).json({ error: 'URL non autorisée' });
  }
  const response = await fetch(req.body.url);
  res.json(await response.json());
});

Stratégie de sécurité pratique

Utilisez le Top 10 OWASP comme point de départ pour votre feuille de route sécurité, pas comme destination finale. Commencez par un modèle de menaces pour votre application : quelles données sont les plus précieuses ? Qui sont les attaquants potentiels ? Quels vecteurs d'attaque sont les plus probables ?

Intégrez les tests de sécurité dans votre pipeline CI/CD avec des outils comme OWASP ZAP (DAST), Semgrep (SAST) et Snyk (SCA). Automatisez ce que vous pouvez et planifiez des tests d'intrusion réguliers pour ce que vous ne pouvez pas automatiser.

Conseil Pro

Exécutez un scan de sécurité automatisé après chaque déploiement. Des outils comme OWASP ZAP peuvent s'exécuter comme étape de votre pipeline CI/CD et signaler automatiquement les vulnérabilités avant que le code n'arrive en production.

Partager cet article

Tous les articles