La plupart des scanners de sécurité analysent une pull request comme un correcteur orthographique analyse une phrase : ligne par ligne, isolément. Cela marche pour les évidences — une clé en dur, un eval sur une entrée utilisateur, une dépendance avec une CVE connue. Cela s'effondre pour les vulnérabilités qui font vraiment mal, car les pires ne vivent pas dans un seul diff.
La fusion qui crée un trou
Imaginez deux pull requests ouvertes sur develop :
- La branche A ajoute un handler qui transmet une URL fournie par l'utilisateur à un client HTTP interne. À elle seule, ce client applique une liste d'autorisation, donc pas de SSRF. Sûre.
- La branche B refactore ce même client HTTP et, dans le nettoyage, retire discrètement la liste d'autorisation parce que « rien de non fiable ne l'appelle encore ». Sûre aussi, isolément.
Chaque PR passe la revue. Chaque scanner affiche vert. Puis les deux atterrissent dans develop, et désormais une URL contrôlée par l'attaquant arrive dans un client qui ne vérifie plus vers où elle pointe. Vous avez livré une SSRF qui n'existait dans aucune des deux branches. Aucun outil par PR ne peut la voir, car la vulnérabilité est une propriété de la combinaison, pas de l'un ou l'autre changement.
Pourquoi la revue limitée au diff est structurellement aveugle
Un diff est une vue minuscule et locale. Il vous dit ce qui a changé, pas ce que le changement atteint désormais. Pour attraper une faille de fusion, il faut trois choses qu'un diff ne donne pas :
- Le contexte de tout le code — le graphe d'appels et les frontières de confiance, pour savoir quelles fonctions un changement peut réellement atteindre.
- Les autres branches en cours — quoi d'autre est sur le point d'atterrir sur la même base.
- L'état fusionné prévu — le code tel qu'il existera après les deux fusions, pas tel qu'il existe dans l'une ou l'autre branche aujourd'hui.
L'approche de Stateward
Stateward construit une base de connaissances de tout votre projet — le graphe des modules et des appels, les frontières de confiance, quelles dépendances sont réellement atteignables — et la maintient à chaud entre les exécutions. Quand une pull request vise une branche d'intégration, il ne se contente pas d'analyser ce diff. Il calcule le graphe fusionné prévu à travers les branches sœurs et cherche les chemins qui n'existent qu'après la fusion : une source dans une branche atteignant un sink dans une autre, une protection retirée ici dont quelque chose dépend là-bas.
Quand il trouve une telle interaction, il ne s'arrête pas à « analysez ceci ». Il lance un audit profond ciblé sur l'état fusionné pour confirmer si l'interaction est réellement exploitable, et la signale avec une reproduction et un verdict, avant qu'elle n'atteigne votre branche par défaut.
C'est là toute la différence entre un scanner et un relecteur. Un scanner vérifie une ligne. Un relecteur comprend le système. Attraper les vulnérabilités de fusion est l'un des endroits où cette distinction est la plus nette — et l'une des raisons pour lesquelles j'ai conçu Stateward pour raisonner sur tout le code, pas seulement sur le diff.