La cybersécurité est trop souvent perçue par les développeurs web débutants comme une préoccupation réservée aux experts en sécurité ou aux grandes entreprises. C’est une erreur dangereuse : les attaques les plus courantes ciblent spécifiquement les applications mal sécurisées, indépendamment de leur taille. Une vulnérabilité XSS sur un petit blog peut compromettre tous ses visiteurs. Une injection SQL sur une boutique en ligne peut exposer des milliers de données personnelles. Ce guide vous donne les fondamentaux pratiques pour écrire du code web sécurisé dès le départ.

Les vulnérabilités OWASP Top 10 à connaître absolument

L’OWASP (Open Web Application Security Project) publie tous les quatre ans une liste des dix risques de sécurité les plus critiques pour les applications web. Cette liste est la référence mondiale pour les développeurs, les auditeurs et les entreprises. En 2021, les positions de tête sont occupées par les contrôles d’accès défaillants, les mauvaises configurations de sécurité et les injections — trois catégories directement liées aux pratiques de développement quotidiennes.

L’injection SQL reste l’une des vulnérabilités les plus exploitées malgré sa connaissance depuis plus de vingt ans. Elle survient lorsque des données utilisateur sont intégrées directement dans une requête SQL sans validation ni échappement. Un attaquant peut alors manipuler la requête pour extraire toute la base de données, modifier des données ou contourner l’authentification. La prévention est simple : utilisez toujours des requêtes préparées avec des paramètres liés, jamais de concaténation de chaînes.

Le Cross-Site Scripting (XSS) permet à un attaquant d’injecter du JavaScript malveillant dans vos pages web, qui s’exécutera dans le navigateur de vos visiteurs. Les conséquences vont du vol de cookies de session à la redirection vers des sites de phishing. Il existe trois types de XSS : reflected (via URL), stored (persisté en base) et DOM-based. La défense principale est l’échappement systématique de toute donnée affichée côté HTML, et l’utilisation d’une Content Security Policy stricte.

HTTPS, certificats SSL/TLS et hsts

En 2026, utiliser HTTP sans chiffrement sur un site en production est inacceptable. HTTPS chiffre toutes les communications entre le navigateur et votre serveur, empêchant les attaques de type man-in-the-middle. Les navigateurs affichent désormais des avertissements explicites sur les sites HTTP, ce qui impacte directement la confiance des utilisateurs et le référencement Google. Let’s Encrypt fournit des certificats SSL/TLS gratuits avec renouvellement automatique.

La configuration TLS elle-même doit être sécurisée. Désactivez les versions obsolètes de TLS (1.0 et 1.1 sont vulnérables), preferez TLS 1.3 qui est plus rapide et plus sécurisé, et choisissez des cipher suites modernes. L’outil SSL Labs de Qualys permet d’analyser gratuitement la configuration TLS de votre serveur et donne une note de A+ à F selon les paramètres. Viser au minimum un A est un objectif raisonnable pour tout site en production.

L’en-tête HSTS (HTTP Strict Transport Security) indique aux navigateurs de ne jamais charger votre site en HTTP, même si l’URL commence par http://. En ajoutant Strict-Transport-Security: max-age=31536000; includeSubDomains; preload à vos réponses HTTP, vous forcez HTTPS pour un an et pouvez soumettre votre domaine à la preload list des navigateurs. Cette liste est intégrée directement dans Chrome, Firefox et Safari — vos utilisateurs seront protégés dès leur première visite.

Validation et sanitisation des entrées utilisateur

La règle d’or de la sécurité web est de ne jamais faire confiance aux données qui viennent de l’extérieur — formulaires, paramètres URL, headers HTTP, webhooks, fichiers uploadés. Toute donnée externe doit être validée (vérifier que la valeur respecte le format attendu) et sanitisée (nettoyer ou encoder les caractères dangereux) avant d’être utilisée dans une requête SQL, affichée en HTML ou transmise à un service tiers.

La validation doit être double : côté client (JavaScript) pour l’expérience utilisateur, et impérativement côté serveur pour la sécurité. La validation client peut être contournée en désactivant JavaScript ou en modifiant la requête HTTP avec des outils comme Burp Suite. La validation serveur est la seule garantie réelle. En Node.js, express-validator offre un DSL déclaratif pour définir les règles de validation de chaque champ de formulaire.

Pour les données qui seront affichées dans du HTML, la sanitisation avec une bibliothèque comme DOMPurify est indispensable. DOMPurify parse le HTML et supprime tout élément ou attribut pouvant exécuter du JavaScript (script, onerror, onload, href= »javascript:… », etc.), tout en conservant la mise en forme légitime. C’est la bonne approche pour les commentaires utilisateurs ou tout champ permettant du HTML riche — jamais la concaténation directe.

// Validation et sanitisation cote serveur (Node.js + Express)
const { body, validationResult } = require("express-validator");
const DOMPurify = require("isomorphic-dompurify");

app.post("/api/comment", [
  body("text").trim().isLength({ min: 1, max: 500 }).escape(),
  body("email").isEmail().normalizeEmail(),
  body("username").trim().alphanumeric().isLength({ min: 3, max: 30 })
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  // Le HTML potentiel est purifie avant stockage
  const safeText = DOMPurify.sanitize(req.body.text);
  // Utiliser des requetes preparees pour eviter SQL injection
  db.query("INSERT INTO comments (text, email) VALUES (?, ?)",
    [safeText, req.body.email]);
  res.json({ success: true });
});

Gestion sécurisée des mots de passe et authentification

Les mots de passe ne doivent jamais être stockés en clair ou avec un simple hachage MD5 ou SHA-1. Ces algorithmes peuvent être cassés en quelques secondes avec des rainbow tables ou des GPUs modernes. Utilisez bcrypt, Argon2 ou scrypt — des algorithmes de hachage conçus spécifiquement pour les mots de passe, avec un facteur de coût configurable qui ralentit intentionnellement le calcul pour rendre les attaques par force brute prohibitivement coûteuses.

L’authentification multifacteur (MFA) est la mesure individuelle qui réduit le plus efficacement le risque de compromission de compte. Même si un attaquant obtient le mot de passe d’un utilisateur — via une fuite de données tierce, du phishing ou de la force brute — le MFA l’empêche de se connecter sans le second facteur. Implémentez le MFA via des applications TOTP (Google Authenticator, Authy) ou des clés de sécurité hardware U2F/FIDO2.

La gestion des sessions doit utiliser des identifiants cryptographiquement aléatoires (128 bits minimum), stockés dans des cookies avec les attributs HttpOnly (non accessible depuis JavaScript), Secure (transmis uniquement en HTTPS) et SameSite=Lax ou Strict (protection contre les attaques CSRF). Invalidez les sessions côté serveur lors de la déconnexion — ne comptez pas uniquement sur la suppression du cookie côté client, qui peut être ignorée ou contournée.

Headers HTTP de sécurité et Content Security Policy

Les en-têtes HTTP de sécurité sont une ligne de défense supplémentaire que votre serveur peut activer en quelques lignes de configuration. L’en-tête X-Content-Type-Options: nosniff empêche les navigateurs de deviner le type MIME des ressources. X-Frame-Options: DENY empêche votre site d’être chargé dans une iframe (protection contre le clickjacking). Referrer-Policy: strict-origin-when-cross-origin contrôle les informations partagées dans le header Referer.

La Content Security Policy (CSP) est l’outil le plus puissant pour prévenir les attaques XSS. Elle définit précisément d’où peuvent provenir les scripts, styles, images et autres ressources de votre page. Une CSP stricte comme default-src ‘self’; script-src ‘self’ ‘nonce-xxx’; style-src ‘self’ bloque tous les scripts inline et les ressources externes non autorisés explicitement. Même si un attaquant injecte du HTML dans votre page, la CSP empêche l’exécution des scripts malveillants.

Configurer ces en-têtes varie selon votre serveur web. Dans Nginx, un bloc add_header dans la configuration du serveur suffit. Dans Express.js, le middleware Helmet.js configure automatiquement une dizaine d’en-têtes de sécurité avec des valeurs sensées par défaut. L’outil securityheaders.com permet de vérifier les en-têtes de votre site et donne une note explicative pour chaque header manquant ou mal configuré.

Sécurité des dépendances et supply chain attacks

Les dépendances tierces sont souvent le maillon faible de la chaîne de sécurité. La compromission du package npm event-stream en 2018 ou du registre PyPI en 2022 ont montré qu’un attaquant peut cibler toute une chaîne d’approvisionnement logicielle via une seule bibliothèque populaire. Votre application dépend de dizaines ou centaines de packages tiers — chacun est une surface d’attaque potentielle.

La commande npm audit (ou yarn audit, pip-audit pour Python) analyse vos dépendances et signale les vulnérabilités connues. Intégrez cette commande dans votre pipeline CI/CD pour bloquer les builds qui introduisent des dépendances vulnérables. Des services comme Snyk ou Dependabot ouvrent automatiquement des pull requests pour mettre à jour les dépendances vulnérables dès qu’un CVE est publié.

Le verrouillage des versions via package-lock.json ou yarn.lock est une protection contre les substitutions de paquets. Sans lockfile, npm install peut installer une version plus récente d’une dépendance transitive qui a été compromise. Avec un lockfile, les hashes des packages sont vérifiés à chaque installation. En production, utilisez npm ci plutôt que npm install pour garantir l’installation des versions exactes du lockfile.

Protection CSRF et gestion des CORS

Les attaques Cross-Site Request Forgery (CSRF) exploitent le fait que les navigateurs envoient automatiquement les cookies avec chaque requête vers un domaine donné. Un site malveillant peut déclencher une requête vers votre API en profitant des cookies d’authentification déjà présents dans le navigateur de la victime. La protection classique consiste à inclure un token CSRF aléatoire dans chaque formulaire et à vérifier sa présence côté serveur.

Les attributs SameSite des cookies réduisent considérablement le risque CSRF dans les navigateurs modernes. SameSite=Strict empêche les cookies d’être envoyés depuis des sites tiers même pour des requêtes GET. SameSite=Lax autorise les requêtes GET inter-sites (nécessaires pour les redirections OAuth) mais bloque les POST. Ces attributs, combinés à un middleware CSRF pour les APIs qui utilisent des sessions, constituent une protection robuste.

La politique CORS (Cross-Origin Resource Sharing) contrôle quels sites peuvent appeler votre API depuis un navigateur. Une configuration CORS trop permissive comme Access-Control-Allow-Origin: * ouvre votre API à tout site web — un vecteur d’attaque pour voler des données des utilisateurs authentifiés. Configurez CORS pour n’autoriser que les origines légitimes (vos propres domaines frontend), et n’utilisez les credentials CORS qu’avec une liste d’origines explicite, jamais avec le wildcard.

Plan d’action et ressources pour progresser en sécurité

La sécurité s’apprend par la pratique. WebSecurity Academy de PortSwigger est la ressource gratuite la plus complète pour apprendre les vulnérabilités web par des labs interactifs. OWASP WebGoat est une application intentionnellement vulnérable que vous pouvez déployer localement pour pratiquer les attaques et les défenses dans un environnement légal. Ces deux ressources couvrent les vulnérabilités OWASP Top 10 en détail avec des exemples concrets.

Intégrez la sécurité dans votre workflow de développement plutôt que de la traiter comme une étape séparée. Activez les outils d’analyse statique dans votre éditeur (ESLint avec eslint-plugin-security pour JavaScript, Bandit pour Python). Ajoutez les scanners de dépendances dans votre CI/CD. Effectuez des revues de code en gardant l’OWASP Top 10 à l’esprit. Ces pratiques permettent de détecter et corriger les vulnérabilités avant qu’elles n’atteignent la production.

La veille sécurité est indispensable : abonnez-vous aux bulletins de sécurité des technologies que vous utilisez, suivez le CERT-FR et les CVE de vos dépendances clés. Chaque mise à jour de sécurité publiée par un mainteneur de bibliothèque doit être appliquée dans vos projets dans les meilleurs délais. Les attaquants analysent les changelogs de sécurité publiés et ciblent en priorité les installations non mises à jour.

Sources et références

W
WP Admin Lab

Architecte web full-stack. WordPress, performance, data et sécurité. Notes de terrain, tests reproductibles et retours d'expérience.