« kses signifie « keep sensible editing style » et permet de filtrer le HTML entrant selon une liste blanche de balises et d’attributs autorisés », précise la documentation du Codex à propos de cette famille de fonctions de sanitisation, l’une des plus anciennes du cœur de WordPress mais toujours aussi centrale.
Pour un développeur d’extension qui doit accepter du contenu riche – un champ de description longue, un commentaire enrichi, un contenu importé depuis une source externe – la question se pose systématiquement : la fonction générique wp_kses_post() suffit-elle, ou faut-il construire un filtre sur mesure avec wp_kses() directement ?
Ce que fait wp_kses_post par défaut
$contenu_nettoye = wp_kses_post( $contenu_brut );
Cette fonction applique la même liste de balises et d’attributs autorisés que celle utilisée pour le contenu des articles standards : les balises de mise en forme courantes (p, strong, em, a, ul, li…), avec leurs attributs habituels, mais sans balises de script ni d’iframe, et sans attributs d’événements comme onclick.
Quand ce standard devient insuffisant
Un champ de description longue dans une extension de catalogue produit peut légitimement avoir besoin d’accepter des balises que wp_kses_post() autorise déjà ; le problème survient surtout dans le sens inverse : un besoin de restreindre davantage, par exemple pour un champ qui ne doit contenir que du texte enrichi minimal, sans même les liens.

Construire un jeu de balises personnalisé
$balises_autorisees = array(
'strong' => array(),
'em' => array(),
'br' => array(),
);
$contenu_nettoye = wp_kses( $contenu_brut, $balises_autorisees );
Ce tableau associatif définit précisément les balises acceptées et, pour chacune, les attributs autorisés. Une balise a qui doit conserver un attribut href et title, mais rien d’autre, s’écrit ainsi :
$balises_autorisees['a'] = array(
'href' => true,
'title' => true,
);
Le piège de la sur-restriction
Un jeu de balises trop restreint mutile silencieusement un contenu légitime : un rédacteur qui insère une liste à puces dans un champ où seules strong et em sont autorisées se retrouve avec ses balises ul et li supprimées, sans message d’erreur explicite, puisque wp_kses() retire simplement ce qu’elle ne reconnaît pas plutôt que de rejeter la saisie.
Le piège de la sur-permissivité
À l’inverse, ajouter des balises « au cas où » sans réflexion, notamment des attributs qui acceptent des URL ou du contenu exécutable, rouvre potentiellement une faille de script intersite. Un attribut comme style, par exemple, peut permettre certaines attaques via des propriétés CSS spécifiques et mérite d’être exclu sauf besoin réellement justifié.
| Situation | Fonction recommandée |
|---|---|
| Contenu éditorial classique | wp_kses_post() |
| Champ restreint à quelques balises | wp_kses() avec tableau personnalisé |
| Texte simple sans mise en forme | sanitize_text_field() |
| Zone de texte multiligne sans HTML | sanitize_textarea_field() |
Un filtre réutilisable plutôt qu’un tableau dupliqué
function wpm_balises_description_courte() {
return array(
'strong' => array(),
'em' => array(),
);
}
function wpm_nettoyer_description( $contenu ) {
return wp_kses( $contenu, wpm_balises_description_courte() );
}
Centraliser le tableau de balises dans une fonction dédiée évite de le dupliquer à chaque endroit où le nettoyage est appliqué, et facilite son ajustement futur si un nouveau besoin de mise en forme apparaît.
La règle qui guide ce choix : ne jamais autoriser une balise ou un attribut sans savoir précisément pourquoi il est nécessaire pour ce champ précis, pas pour un usage hypothétique futur.
En résumé
wp_kses_post() couvre correctement l’immense majorité des besoins de contenu éditorial dans une extension, et il est préférable de s’y tenir tant que le besoin ne sort pas de ce cadre standard. Un jeu personnalisé via wp_kses() ne se justifie que pour un champ dont le périmètre de mise en forme diffère réellement de celui d’un article, et mérite d’être construit avec la même rigueur qu’une règle de sécurité, ni trop large ni trop stricte.