Reconnaissance, attaque, défense : la sécurité web racontée des deux côtés du pare-feu.
Pourquoi ce livre
La plupart des développeurs apprennent la sécurité par listes d'interdits : échappez vos sorties, utilisez des requêtes préparées, activez HTTPS. On applique, on coche, sans savoir ce que chaque règle bloque au juste. Le jour où une faille sort du catalogue connu, personne ne la voit venir. Hoffman prend le chemin inverse : un tiers du livre pour cartographier une application comme un attaquant, un tiers pour l'attaquer vraiment, et seulement ensuite un tiers pour la défendre. La défense arrive en dernier parce qu'elle ne veut rien dire avant.
C'est exactement le parti que j'ai pris pour le cours sécurité de ce site : montrer comment sqlmap, Burp ou Hydra s'utilisent avant d'expliquer les protections. Ce livre est la version longue de cette conviction. J'ai lu la première édition (2020) ; la deuxième (2024) ajoute du contenu que je détaille plus bas.
Les idées qui restent
1Le hacking est né avant l'ordinateur
On croit volontiers que la sécurité logicielle commence avec le web. Hoffman ouvre sur un siècle d'histoire. En 1932, le mathématicien polonais Marian Rejewski reconstitue le fonctionnement d'Enigma à partir d'une machine volée ; Turing automatise ensuite le déchiffrement en exploitant un détail d'organisation : les Allemands émettaient chaque jour un bulletin météo chiffré, donc au contenu prévisible. Sa machine teste 20 000 configurations en 20 minutes. C'est l'attaque par texte clair connu, toujours enseignée (ch. 1).
Puis viennent les phreakers des années 60. À l'époque, le réseau d'AT&T pilote ses commutateurs par des tonalités qui circulent sur la même ligne que la voix ; or 2 600 Hz est le signal interne qui marque la fin d'un appel. Quiconque émet cette note garde donc la ligne ouverte sans être facturé. Joe Engressia savait la siffler à la bouche ; John Draper découvre que le sifflet jouet des boîtes de céréales Cap'n Crunch la produit exactement. Résultat : des appels internationaux gratuits avec un jouet de petit-déjeuner.
La leçon vaut pour tout le livre : les ingénieurs d'AT&T avaient conçu le réseau pour l'utilisateur honnête, pas pour celui qui détourne les règles du système. « Considérez toujours le pire scénario en premier quand vous concevez des systèmes complexes » (ch. 1).
2Un hacker est d'abord un détective
On imagine l'attaque comme un coup d'éclat technique. Le livre la décrit autrement : « un hacker est avant tout un détective » (ch. 9). Un tiers du livre sert à cartographier une application sans jamais toucher à son code. Les outils tiennent en quelques gestes :
- les opérateurs Google :
site:cible.com -inurl:wwwfait remonter les sous-domaines oubliés ; - archive.org, où traînent des liens vers des serveurs qu'on croyait débranchés ;
- le transfert de zone DNS : deux lignes de bash qui, face à un serveur mal réglé, livrent tous les sous-domaines et leurs IP ;
- le dictionnaire dnscan, bâti sur 86 000 fichiers de zone réels.
Pourquoi tant d'efforts ? La vitrine publique est surveillée en continu, ses bugs corrigés vite. Les serveurs de coulisse (mail, admin, dev) sont « truffés de bugs car beaucoup moins utilisés et exposés » (ch. 4). Le recon ne cherche pas la grande porte : il cherche la porte de service.
3XSS : quatre visages, et le pire passe les filtres
Le fil rouge du livre est une banque fictive, MegaBank. Un client glisse une balise <strong> dans un ticket de support ; l'agent lui répond « comment avez-vous mis ce texte en gras ? ». Le détail est drôle, mais il dit tout : le HTML traverse l'application sans le moindre filtre. La suite l'est beaucoup moins. Le pirate poste cette fois un <script> qui se stocke en base. À chaque ouverture du ticket par un agent, le script s'exécute dans SON navigateur, aspire les noms, emails et téléphones affichés à l'écran, et les envoie vers un serveur pirate (ch. 10). C'est le XSS stocké : le plus rentable, parce qu'il frappe tous ceux qui lisent le ticket.
La famille a trois autres visages :
- le reflected : le code piégé vit dans une URL qu'on vous fait cliquer, il n'est jamais stocké ;
- le DOM-based : tout se passe dans le navigateur, le serveur ne voit rien, donc aucun log ne le trahit ;
- le mutation XSS, le plus retors : le navigateur réécrit lui-même le HTML après le nettoyage, et rouvre une faille qu'on croyait fermée. C'est ainsi qu'en 2019 un code de Masato Kinugawa a traversé DOMPurify, le nettoyeur de référence.
La défense tient en une règle (ch. 22) : une donnée venue de l'utilisateur n'entre jamais dans la page comme du HTML, seulement comme du texte. La 2e édition va plus loin avec les payloads polyglottes (un même code valide dans plusieurs contextes à la fois) et les contournements d'encodage.
4CSRF : votre navigateur signe à votre place
Une requête HTTP part toujours avec vos cookies, même quand vous n'avez rien demandé. Tout le CSRF tient dans cette phrase. L'exemple du livre : une image invisible de zéro pixel, dont l'adresse pointe vers le virement de mega-bank.com, avec le compte du pirate et le montant glissés dans l'URL. La page s'affiche, le navigateur « charge l'image », et le virement part avec votre session ouverte (ch. 11). Variante plus sournoise : un faux formulaire de connexion qui, à l'envoi, déclenche en réalité un virement pendant que vous croyez vous identifier.
La défense s'empile en trois couches (ch. 23) :
- une règle d'architecture d'abord : un GET ne modifie jamais l'état du serveur (il lit, il n'écrit pas) ;
- la vérification des en-têtes origin et referer, qui disent d'où vient vraiment la requête ;
- enfin le token anti-CSRF sans état : un jeton unique (identifiant, horodatage et nonce chiffrés ensemble côté serveur) que la page piégée n'a aucun moyen de deviner.
La règle « un GET ne change rien » reste un fondement d'API propre, attaque ou pas.
5L'injection monte en grade : la base, l'outil, le système
« Injection » évoque SQL, et on s'arrête souvent là. Hoffman gradue la menace en trois paliers (ch. 13) :
- l'injection SQL : un
user_idvalant'1=1'renvoie la table entière, un'; DROP TABLE users;'la supprime ; - l'injection de code : la cible n'est plus la base mais un outil en ligne de commande appelé par le serveur ; un nom de fichier non filtré passé à un convertisseur d'images suffit à écraser le logo du site ;
- l'injection de commande, le palier le plus grave : on parle directement au système d'exploitation.
exec(`rm /videos/raw/${req.body.name}`); // name = "myVideo.mp4 && rm -rf /videos/converted/" // le serveur exécute LES DEUX commandes
À ce niveau, l'attaquant lit /etc/passwd, récupère des clés SSH, et réécrit les logs pour effacer ses traces.
La défense (ch. 25) :
- les requêtes préparées : la requête est compilée avant l'arrivée des variables, donc un
UPDATEinjecté reste une vulgaire chaîne de texte ; - une liste blanche des commandes que le serveur a le droit de lancer ;
- un utilisateur système distinct par module, aux permissions minimales.
La 2e édition ajoute les trois façons de faire sortir les données volées : dans la réponse elle-même, hors bande, ou par inférence (temps de réponse, messages d'erreur).
6La chaîne casse au maillon le moins testé
Votre code est relu et audité ; vos centaines de dépendances npm, non. Hoffman documente deux affaires de 2018 (ch. 15) :
- eslint-scope : les identifiants volés d'un mainteneur ont permis de publier une version piégée qui volait, à son tour, les identifiants de tous ceux qui l'installaient ;
- event-stream : une sous-dépendance obfusquée (flatmap-stream) cherchait des portefeuilles Bitcoin sur les machines qui la faisaient tourner.
L'attaque qui va avec rapporte à tous les coups : repérer les versions exactes que fait tourner une cible (la page 404 de Rails qui date le framework, le header X-Powered-By, les identifiants MongoDB reconnaissables à leur format), les chercher dans la base CVE publique, dérouler l'exploit déjà documenté. Comme le dit le livre : « une chaîne n'est jamais plus solide que son maillon le plus faible, et ce maillon est souvent celui qui a subi l'assurance qualité la moins rigoureuse » (ch. 15).
La défense (ch. 27) : verrouiller l'arbre de dépendances sur des versions exactes, voire des SHAs Git, et surveiller le flux des CVE.
7La défense se gagne avant la première ligne de code
Traiter la sécurité en fin de projet est l'erreur la plus chère du métier. Le chiffre que cite Hoffman (ch. 18, d'après le NIST) : corriger une faille en phase de conception coûte 30 à 60 fois moins cher qu'en production. La raison est mécanique : une fois des clients branchés sur une API mal conçue, la re-architecturer casse leurs intégrations.
D'où la défense en profondeur. Dans son exemple de messagerie, une même donnée traverse cinq couches, et chaque couche doit porter sa propre protection. Sécuriser la première seulement, c'est offrir un boulevard à l'endpoint d'envoi groupé que quelqu'un ajoutera dans six mois, et qui la contournera tout droit.
Et une règle d'or sans exception : ne réinventez jamais la cryptographie. SHA-3, c'est vingt ans de R&D et d'audits, disponible gratuitement dans OpenJDK. L'avertissement du livre : « les applications pleines de bases de données maison, de cryptographie maison et d'optimisations matérielles spéciales sont souvent les plus faciles à pénétrer » (ch. 7).
8Des mitigations, pas des fixes
Croire qu'un scanner suffit est le dernier piège. Le livre range les failles en deux familles (ch. 19) :
- les archétypes (XSS, injection, CSRF) : les analyseurs statiques comme Checkmarx, Bandit ou Brakeman les détectent bien ;
- les bugs logiques, invisibles par construction : une API qui promeut celui qui glisse le bon champ dans sa requête. Aucun outil ne sait que ce champ n'a rien à y faire ; il faut un humain qui connaît le métier.
// ✗ mass assignment : le serveur recopie TOUT le corps reçu
POST /api/profil { "nom": "Alice", "isMember": true }
user.update(req.body) // isMember passe → Alice s'auto-promeut
// ✓ liste blanche : seuls les champs autorisés sont pris
user.update({ nom: req.body.nom }) // isMember est ignoré
Côté process, un chiffre qui pique (ch. 21) : environ 25 % des vulnérabilités sont des régressions de bugs déjà fermés. La règle qui en découle : tout bug de sécurité fermé embarque son propre test de régression, sans exception. Et pour prioriser le reste, le score CVSS en trois étages (base, temporel, environnemental) replace chaque faille dans votre contexte : la même injection ne pèse pas pareil dans un bac à sable jetable et dans un dossier médical.
La lucidité finale du livre est dans son vocabulaire : les défenses s'appellent « mitigations », pas « fixes » (ch. 16), parce qu'aucune n'est jamais définitive.
9Ce que la 2e édition (2024) ajoute
La deuxième édition, parue début 2024, répond à la demande la plus fréquente des lecteurs : du contenu avancé. Hoffman annonce 120 pages de plus, et la table des matières confirme neuf chapitres entièrement nouveaux, attaque et défense en miroir :
- les attaques côté client : prototype pollution, clickjacking poussé jusqu'à l'exploitation de la caméra et du micro, tabnabbing ;
- les attaques sur les données et les objets : mass assignment, IDOR, désérialisation ;
- les failles de logique métier : points de fidélité, crédits, quasi-monnaie ;
- un threat modeling pas à pas, et un chapitre entier de configuration sécurisée (Strict CSP, CORS, HSTS, COOP, Subresource Integrity).
Un seul de ces nouveaux chapitres pour donner le ton, la prototype pollution (côté client) : en JavaScript, tous les objets héritent d'un même parent via __proto__. Écrire dedans contamine tous les objets du programme d'un coup.
// l'attaquant envoie ce JSON, qu'un merge naïf recopie sans filtrer
const payload = JSON.parse('{"__proto__": {"isAdmin": true}}')
merge({}, payload) // le merge copie __proto__ dans le parent commun…
({}).isAdmin // → true ! un objet VIDE est devenu admin
Une vérification if (user.isAdmin) ailleurs dans le code passe désormais pour n'importe qui. Le Zero Trust entre aussi dans le chapitre d'architecture. La 2e édition comble précisément ce qui avait vieilli dans la première : si vous achetez aujourd'hui, prenez celle-là.
Trois choses que je ne savais pas avant de le lire
- Le script de brute force de sous-domaines du livre évite
dns.lookupde Node : sous son air asynchrone, il repose surgetaddrinfo, qui est synchrone ;dns.resolve, lui, parallélise vraiment. - Le premier condamné pour hacking aux États-Unis est Robert Morris (1988) : son ver a infecté quelque 15 000 machines en une journée ; verdict, 3 ans de probation et 10 050 dollars d'amende.
- La page 404 par défaut de Ruby on Rails permet de dater un framework : trois retouches cosmétiques (2012, 2013, 2017) suffisent à encadrer la version, donc ses CVE connues.
Mon avis, honnêtement
Ce qui ne vieillira pas : la structure. Chaque attaque de la partie II a son chapitre de défense en partie III, et on comprend enfin ce que chaque protection bloque, parce qu'on vient de mener l'attaque soi-même. Le pari pédagogique tient aussi : des concepts plutôt que des outils, du JavaScript lisible plutôt que des captures d'écran de Burp. Après lecture, on ne relit plus son propre code de la même façon, et c'est le vrai livrable du livre.
La première édition accuse son âge sur des points précis. SameSite, devenu la défense CSRF par défaut de tous les navigateurs, n'y figure pas. Les outils d'audit automatique de dépendances (npm audit, Dependabot) non plus. L'API Twitter du chapitre recon est morte depuis 2023. Et le pentester confirmé n'y apprendra pas grand-chose : Hoffman lui-même décrivait sa 1re édition comme destinée aux profils débutants et intermédiaires. La 2e édition corrige une bonne partie de ces trous, le chapitre configuration en tête.
Pourquoi le lire en 2026, alors qu'une part croissante du code est écrite par des agents IA ? Justement pour ça. Les modèles reproduisent les archétypes de vulnérabilités présents dans leur corpus d'entraînement, et personne d'autre que vous ne chassera les bugs logiques de votre métier : aucun scanner ni aucun LLM ne sait que isMember: true n'a rien à faire dans ce payload. Comprendre l'attaque, c'est savoir relire du code, qu'il vienne d'un junior ou d'un agent.
Odilon
Toujours valable en 2026 ?
Les concepts, oui : les archétypes d'attaque du livre sont toujours ceux que l'OWASP recense, et la méthode recon → attaque → défense ne périme pas. Pour les détails datés de la 1re édition, la 2e (2024) corrige l'essentiel. Ce qui manque encore aux deux : la sécurité des applications qui embarquent des LLM (prompt injection), hors de leur périmètre.
Pour qui ?
Lisez-le si
- Vous développez pour le web et n'avez jamais regardé votre application avec les yeux d'un attaquant
- Vous appliquez CSP, tokens CSRF et requêtes préparées « parce qu'il le faut », sans savoir précisément ce que chacun bloque
- Vous faites des revues de code et voulez y chasser autre chose que du style
- Vous visez un premier poste en sécurité applicative avec un bagage de développeur
Passez si
- Vous pentestez déjà pour vivre : vous n'y apprendrez pas grand-chose, et les outils du métier (Burp, sqlmap, Metasploit) sont volontairement à peine effleurés
- Vous cherchez un guide d'outillage prêt à l'emploi plutôt que des concepts
- Il vous faut des exemples dans votre langage : ici, tout est JavaScript et Node
Pour aller plus loin
Le cours Sécurité web de ce site (20 leçons, OWASP 2025) pratique exactement ces attaques dans des labos vivants, injection SQL et XSS compris, et le cours HTTP couvre le protocole que toutes ces attaques empruntent.
Commentaires (0)