# Un audit de sécurité par IA a raté une faille qu’un humain aurait vue en 5 min

> Un outil d'audit assisté par IA a validé à tort une extension vulnérable, illustrant les limites actuelles de la revue de code automatisée par grand modèle de langage.

- Auteur : Clément Hadrot
- Publié le : 2025-11-29
- Mis à jour le : 2025-11-29
- Catégorie : Sécurité
- URL : https://wpmoderne.dev.wordpress-developpement.fr/securite/audit-securite-ia-faille-ratee/

## L’essentiel

- L'outil a analysé le code sans en tester le comportement réel
- Un contournement trivial d'un contrôle d'accès est passé inaperçu
- Un humain l'a repéré en relisant la logique métier, pas le code isolément

Un client, éditeur d'une extension WordPress de gestion de billetterie pour événements, avait adopté un outil d'audit de sécurité assisté par IA pour accélérer sa revue de code avant chaque nouvelle version publiée sur le répertoire officiel. L'outil, qui analyse le code source à la recherche de vulnérabilités en s'appuyant sur un grand modèle de langage entraîné à reconnaître des motifs de code dangereux, avait validé la nouvelle version 3.4.0 de l'extension sans relever la moindre alerte critique, avec un rapport concluant à un niveau de risque global jugé faible.

Une revue manuelle complémentaire, commandée par prudence avant une mise à jour touchant à la gestion des places réservées, a mis au jour en moins d'une demi-journée une faille que l'outil automatisé avait totalement manquée : un contrôle d'accès contournable en modifiant un simple paramètre d'URL, permettant à n'importe quel visiteur non connecté d'annuler la réservation d'un autre utilisateur, à condition de connaître ou de deviner son identifiant de réservation.

## Ce que l'outil d'audit par IA avait analysé

Le code en question exposait une route REST permettant d'annuler une réservation, avec ce qui ressemblait, à première lecture, à une vérification de permission tout à fait standard :

```
register_rest_route( 'billetterie/v1', '/reservation/(?P<id>\d+)/annuler', array(
    'methods'  => 'POST',
    'callback' => 'billetterie_annuler_reservation',
    'permission_callback' => function( $request ) {
        return is_user_logged_in();
    },
) );

function billetterie_annuler_reservation( $request ) {
    $reservation_id = $request['id'];
    billetterie_marquer_annulee( $reservation_id );
    return array( 'statut' => 'annulee' );
}
```

L'outil d'audit par IA a correctement identifié la présence d'un `permission_callback`, un point de vérification que de nombreuses failles réelles omettent purement et simplement, ce qui explique en partie pourquoi il a classé cette route comme protégée. Ce que l'analyse n'a pas relevé, c'est que `is_user_logged_in()` vérifie uniquement qu'un utilisateur quelconque est connecté au site, sans jamais vérifier que cet utilisateur est bien le propriétaire de la réservation qu'il tente d'annuler. N'importe quel visiteur disposant d'un compte, même le plus basique, gratuit et sans historique, pouvait annuler la réservation de n'importe qui d'autre en connaissant simplement son identifiant numérique, une valeur incrémentale et donc facilement devinable ou énumérable.

## Pourquoi l'IA n'a pas vu le problème

> L'essentiel à retenir : L'outil a analysé le code sans en tester le comportement réel ; Un contournement trivial d'un contrôle d'accès est passé inaperçu ; Un humain l'a repéré en relisant la logique métier, pas le code isolément

Cette faille appartient à une catégorie bien documentée, la référence directe non sécurisée à un objet (IDOR, *Insecure Direct Object Reference*), l'un des risques les plus anciens et les mieux répertoriés en sécurité applicative. Un outil d'audit par IA correctement entraîné aurait dû, en théorie, la reconnaître. Ce qui a fait défaut ici tient à la manière dont l'outil raisonne : il évalue la présence ou l'absence de motifs de vérification (un `permission_callback` existe-t-il, une fonction d'échappement est-elle appelée), mais peine encore à raisonner sur la cohérence sémantique entre l'objet manipulé et le sujet qui agit dessus, c'est-à-dire à se poser la question « est-ce que ce contrôle vérifie vraiment ce qu'il devrait vérifier, ou seulement quelque chose qui y ressemble ? ».

`is_user_logged_in()` ressemble, syntaxiquement, à un contrôle d'accès légitime : c'est une fonction WordPress reconnue, utilisée abondamment dans du code sain. L'outil a probablement associé sa présence à un score de confiance élevé sans pousser plus loin l'analyse jusqu'à comparer l'identité de l'utilisateur courant avec le propriétaire réel de la ressource visée, une inférence qui demande de suivre la donnée (l'identifiant de réservation) à travers plusieurs fonctions pour vérifier où, et si, une comparaison de propriété a réellement lieu.

## Comment l'audit manuel l'a repéré

La méthode employée par l'auditeur humain n'avait rien de sophistiqué : elle a consisté à se poser systématiquement, pour chaque route manipulant une ressource identifiée par un paramètre (un identifiant de réservation, de commande, d'utilisateur), la question suivante : « Qu'est-ce qui, dans ce code, garantit que la personne connectée est bien celle à qui appartient cette ressource ? ». En cherchant cette garantie explicite dans la fonction `billetterie_annuler_reservation`, l'auditeur n'a trouvé aucune comparaison entre l'identifiant de l'utilisateur connecté et le propriétaire de la réservation, ce qui a immédiatement signalé le problème, indépendamment de toute connaissance préalable de la faille.

## Le correctif appliqué

La correction a consisté à ajouter la vérification de propriété manquante, directement dans le `permission_callback`, là où elle doit se trouver pour bloquer la requête avant même l'exécution de l'action :

```
'permission_callback' => function( $request ) {
    if ( ! is_user_logged_in() ) {
        return false;
    }
    $reservation = billetterie_get_reservation( $request['id'] );
    return $reservation && $reservation->user_id === get_current_user_id();
},
```

## Ce que ça révèle sur les limites actuelles de la revue automatisée

Cet incident ne condamne pas l'usage des outils d'audit assistés par IA, qui restent précieux pour couvrir rapidement un grand volume de code et repérer des motifs de vulnérabilités classiques (injections, absence totale de vérification, fonctions dangereuses). Il illustre en revanche une limite bien réelle et actuelle : ces outils excellent à détecter l'absence d'un contrôle, mais peinent encore à évaluer la pertinence sémantique d'un contrôle présent, c'est-à-dire à vérifier qu'il porte bien sur la bonne question. Un `permission_callback` qui existe rassure un outil automatisé ; seul un humain qui se demande « protège-t-il vraiment ce qu'il devrait protéger ? » aurait posé la bonne question.

> Un contrôle d'accès qui existe n'est pas la même chose qu'un contrôle d'accès qui vérifie la bonne chose. Cette nuance échappe encore trop souvent à l'analyse automatisée.

## Ce que l'éditeur a changé dans son processus

L'éditeur de l'extension a conservé son outil d'audit par IA, qui reste utile en première passe pour gagner du temps sur les vérifications les plus mécaniques, mais a réintroduit une revue manuelle systématique, obligatoire, sur toute route qui manipule une ressource identifiée par un paramètre appartenant potentiellement à un utilisateur (réservation, commande, message privé). Cette catégorie de vérification, jugée trop sensible pour être déléguée entièrement à un outil automatisé en l'état actuel de sa maturité, reste désormais une étape humaine incontournable du processus de publication.
