do_action( 'wp_after_insert_post', $post_id, $post, $update, $post_before ) : cette ligne, présente dans wp-includes/post.php, définit exactement le moment où ce hook intervient. Un développeur d’extension qui cherche à y accrocher un contrôle de sécurité doit d’abord comprendre ce que « après » signifie concrètement pour l’état de la base de données.
Introduit en WordPress 5.6, wp_after_insert_post a été conçu pour résoudre un problème précis : donner un point d’ancrage fiable une fois qu’un article, ses métadonnées et ses taxonomies sont tous enregistrés de façon cohérente. C’est une excellente nouvelle pour synchroniser un moteur de recherche externe ou déclencher un webhook. C’est un piège pour qui espère y bloquer un contenu indésirable.
Ce que « après » implique réellement
Au moment où wp_after_insert_post se déclenche, la ligne existe déjà dans la table wp_posts, ses métadonnées sont déjà dans wp_postmeta, et ses termes sont déjà associés dans wp_term_relationships. Retourner un WP_Error depuis un callback accroché à ce hook ne fait rien : l’action ne transmet son retour à personne, et rien n’empêche l’écriture déjà effectuée d’exister.
Une extension de sécurité qui tenterait de « refuser » un contenu à ce stade n’a qu’une option : supprimer ou modifier après coup, avec wp_delete_post() ou wp_update_post(). Le contenu malveillant aura donc, ne serait-ce que quelques millisecondes, existé en base, potentiellement été indexé par un cache d’objets, ou transmis à un webhook accroché plus tôt dans la même requête.
Une fenêtre d’exposition, même courte, compte
Sur un site à fort trafic ou exposant une API REST publique, cette fenêtre n’est pas seulement théorique. Un contenu injecté via wp_insert_post() peut être lu par une requête REST concurrente avant même que le nettoyage tardif n’ait eu lieu. Pire, si une extension tierce a elle-même accroché un traitement sur save_post ou wp_insert_post à une priorité plus faible, elle aura pu propager la donnée non filtrée avant que le contrôle de sécurité intervienne.
wp_after_insert_posts’exécute aprèssave_post, lui-même déjà postérieur à l’écriture.- Aucune donnée renvoyée par un callback accroché ici ne remonte au code appelant.
- Une suppression a posteriori laisse une trace dans les journaux de révisions et le cache d’objets.

Où placer le contrôle pour qu’il ait un effet réel
Le filtre content_save_pre s’exécute avant l’écriture, directement sur le contenu qui sera inséré. C’est là qu’un filtrage ou un rejet a un sens, puisqu’il peut modifier la valeur avant qu’elle n’atteigne la requête SQL d’insertion.
add_filter( 'content_save_pre', function ( $content ) {
if ( preg_match( '/<script\b/i', $content ) ) {
// On assainit avant l'écriture, pas après.
$content = wp_kses_post( $content );
}
return $content;
} );
Pour un rejet complet plutôt qu’un simple nettoyage, la fonction wp_insert_post_data offre un filtre plus adapté encore, car il reçoit à la fois les données à écrire et les données brutes soumises, avant tout appel SQL.
Distinguer validation et réaction
Il existe malgré tout un usage légitime de wp_after_insert_post pour un module de sécurité : la détection et l’alerte, pas le blocage. Un scanner qui journalise une tentative suspecte, avertit un administrateur ou déclenche une mise en quarantaine asynchrone trouve ici un point d’ancrage cohérent, à condition de ne jamais prétendre avoir empêché l’écriture initiale.
Un exemple de confusion fréquente
Un module analysé lors d’une revue de code appelait remove_action sur lui-même après un rejet, pensant ainsi « annuler » l’insertion. En réalité, l’article restait présent dans wp_posts avec le statut défini au moment de l’appel initial à wp_insert_post(), souvent publish. La seule chose annulée était l’exécution future du même callback sur la même requête, ce qui n’a strictement aucun rapport avec la présence du contenu en base.
Retenue d’expérience : un hook nommé « after » l’est vraiment, dans son sens le plus littéral. Il ne s’agit jamais d’un point d’interception, seulement d’un point d’observation ou de réaction.
Notion à retenir
La chronologie des hooks autour de l’écriture d’un contenu WordPress suit un ordre strict : les filtres sur le contenu brut, puis l’insertion SQL, puis save_post, puis enfin wp_after_insert_post. Un développeur d’extension de sécurité doit choisir son point d’ancrage en fonction de l’effet recherché : filtrer et bloquer en amont, observer et réagir en aval. Confondre les deux ne provoque pas d’erreur visible immédiate, ce qui rend cette classe de défaut particulièrement difficile à repérer sans lecture attentive du code source de wp-includes/post.php.