Le cabinet d’avocats qui nous a contactés rédigeait ses analyses juridiques directement dans WordPress, en s’appuyant sur une extension de traduction automatique assistée par IA pour produire une version anglaise de chaque article destinée à sa clientèle internationale. Le workflow éditorial prévoyait plusieurs relectures internes avant publication, parfois échelonnées sur plusieurs semaines pour les analyses les plus sensibles, touchant à des dossiers en cours non encore publics.
L’alerte est venue d’un associé du cabinet, qui a remarqué qu’un brouillon rédigé la veille au soir, jamais publié ni même partagé en dehors de l’équipe de rédaction, apparaissait déjà traduit et proposé à la validation dans l’interface de l’extension le lendemain matin. Ce constat, en apparence anodin, soulevait une question bien plus sérieuse : à quel moment exact ce contenu, encore à l’état de brouillon confidentiel, avait-il quitté les serveurs du cabinet pour être transmis à un service tiers de traduction ?
Comprendre le déclencheur de l’envoi
L’inspection du code de l’extension, un plugin de traduction assez répandu proposant une intégration directe avec une API de traduction par grand modèle de langage, a montré que l’envoi vers l’API externe se déclenchait sur le hook save_post, sans aucune vérification du statut de publication de l’article concerné :
add_action( 'save_post', function( $post_id, $post ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
// Aucune vérification de $post->post_status ici.
traduction_ia_envoyer_a_lapi( $post->post_content, $post_id );
}, 10, 2 );
Le hook save_post se déclenche à chaque enregistrement d’un article, y compris lors des sauvegardes automatiques de brouillon que l’éditeur de blocs effectue toutes les soixante secondes par défaut pendant la rédaction, via wp_autosave. Concrètement, le simple fait de laisser un brouillon ouvert pendant la rédaction suffisait à déclencher, minute après minute, l’envoi du contenu en cours de rédaction vers une API tierce, bien avant toute décision éditoriale de le traduire ou de le publier.
Ce que la documentation de l’extension ne disait pas

La documentation publique de l’extension, consultée avant son installation par l’équipe technique du cabinet, mentionnait effectivement l’usage d’une API tierce pour la traduction, avec un lien vers la politique de confidentialité du fournisseur d’IA. Elle ne précisait en revanche à aucun moment que cet envoi se déclenchait dès la phase de rédaction, sur du contenu à l’état de brouillon, plutôt qu’au moment où l’utilisateur cliquait explicitement sur un bouton « Traduire ». Cette omission n’était probablement pas malveillante : l’éditeur du plugin avait sans doute choisi cette architecture pour que la traduction soit déjà prête au moment où l’utilisateur la demanderait, un choix d’expérience utilisateur qui ignorait les implications de confidentialité pour du contenu sensible non finalisé.
Pour un cabinet d’avocats, cette situation posait un problème direct de confidentialité professionnelle : des éléments d’analyse juridique en cours de rédaction, potentiellement liés à des dossiers non publics, transitaient vers les serveurs d’un tiers, hors de tout accord de traitement de données ou de clause de confidentialité spécifique à ce type d’usage.
Le correctif : filtrer strictement par statut de publication
La correction appliquée a consisté à n’autoriser l’envoi vers l’API de traduction que pour les articles ayant atteint un statut éditorial validé, en ajoutant un filtre explicite avant l’appel externe :
add_action( 'save_post', function( $post_id, $post ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
$statuts_autorises = array( 'pending' ); // relecture terminée, en attente de publication
if ( ! in_array( $post->post_status, $statuts_autorises, true ) ) {
return;
}
// Un indicateur explicite, coché manuellement par le rédacteur, reste requis.
if ( 'oui' !== get_post_meta( $post_id, 'pret_pour_traduction', true ) ) {
return;
}
traduction_ia_envoyer_a_lapi( $post->post_content, $post_id );
}, 10, 2 );
Ce correctif introduit une double barrière : un statut éditorial minimal (l’article a quitté le stade de brouillon actif) et une case à cocher explicite gérée par le rédacteur lui-même, pour qu’aucun envoi ne se déclenche sans une décision humaine consciente. Cette double vérification a été préférée à une simple condition sur le statut, jugée insuffisante compte tenu de la sensibilité des contenus traités par ce client.
Les questions à poser avant d’adopter ce type d’extension
Cet incident a conduit le cabinet, avec l’aide de son responsable de la conformité, à établir une grille de questions systématique avant l’adoption de toute extension impliquant un envoi de contenu vers un service d’IA externe :
- À quel moment exact du cycle de vie du contenu l’envoi se déclenche-t-il : sauvegarde automatique, sauvegarde manuelle, ou action explicite de l’utilisateur ?
- Le contenu envoyé inclut-il des révisions ou des brouillons, ou uniquement la version validée pour publication ?
- Le fournisseur d’IA tiers conserve-t-il le contenu envoyé, et pour quelle durée, au-delà du traitement immédiat ?
- Existe-t-il un moyen de restreindre l’envoi à certains types de contenu ou certaines catégories, pour exclure les dossiers les plus sensibles ?
Un brouillon n’est pas un contenu à moitié publié, c’est un contenu qui n’a pas encore reçu l’autorisation d’exister en dehors de l’équipe qui l’a rédigé. Aucune automatisation ne devrait pouvoir décider seule de franchir cette frontière.
Ce que ça révèle
Cette affaire illustre un risque appelé à se généraliser avec la multiplication des extensions embarquant des fonctionnalités d’intelligence artificielle générative : la frontière entre « le contenu existe dans WordPress » et « le contenu quitte WordPress vers un tiers » devient de plus en plus floue à mesure que ces intégrations se déclenchent automatiquement, en arrière-plan, sur des hooks aussi fréquents que save_post. Pour tout contenu sensible, la prudence impose de vérifier précisément quel événement déclenche un envoi externe, plutôt que de se fier à la seule mention d’une politique de confidentialité générique dans la documentation du plugin.