# Nettoyer la réponse HTML d’un modèle de langage avant de l’insérer en base

> Sécuriser un contenu HTML généré par une IA avant son enregistrement, entre balises non fermées et scripts indésirables.

- Auteur : WordPress Développement
- Publié le : 2023-02-21
- Mis à jour le : 2023-02-21
- Catégorie : IA &amp; MCP
- URL : https://www.wpmoderne.fr/ia-mcp/nettoyer-html-reponse-llm-avant-insertion/

## L’essentiel

- Un modèle de langage peut produire du HTML mal formé
- wp_kses_post filtre sans tout supprimer
- Toujours valider avant d'enregistrer, jamais après affichage

`<script>alert('test')</script>` : voilà, sous une forme volontairement simple, le genre de fragment qu'une réponse de modèle de langage peut contenir sans prévenir, même lorsque la consigne demandait un texte au format prose. Un modèle génère du texte, pas du HTML garanti valide, et rien n'empêche qu'une balise ouverte reste sans fermeture ou qu'un attribut disparaisse en cours de génération.

Enregistrer ce contenu tel quel dans `post_content` revient à faire confiance à un texte dont on ne contrôle ni la structure ni les intentions, ce qui pose un problème de sécurité identique à celui d'une saisie utilisateur non filtrée.

## Pourquoi le nettoyage doit intervenir avant l'enregistrement

Filtrer un contenu au moment de l'affichage, avec `the_content` par exemple, protège les visiteurs mais laisse le contenu brut, potentiellement dangereux, stocké en base. Un export de contenu, une synchronisation vers un autre site ou un appel direct à la base de données contournerait alors la protection. Le nettoyage doit avoir lieu avant l'écriture, pas seulement avant l'affichage.

## Utiliser wp_kses_post plutôt que réinventer un filtre

La fonction cœur `wp_kses_post` applique la même liste de balises et d'attributs autorisés que celle utilisée pour le contenu des articles rédigés par un utilisateur disposant du rôle `editor`. Elle constitue un point de départ solide, déjà éprouvé sur des millions de sites :

> L'essentiel à retenir : Un modèle de langage peut produire du HTML mal formé ; wp_kses_post filtre sans tout supprimer ; Toujours valider avant d'enregistrer, jamais après affichage

```
function inserer_texte_genere( int $post_id, string $html_brut ): void {
    $html_propre = wp_kses_post( $html_brut );

    if ( empty( trim( wp_strip_all_tags( $html_propre ) ) ) ) {
        error_log( 'Contenu vide après nettoyage, article ' . $post_id );
        return;
    }

    wp_update_post( array(
        'ID'           => $post_id,
        'post_content' => $html_propre,
    ) );
}
```

### Les balises que wp_kses_post supprime silencieusement

Les balises `<script>`, `<iframe>` ou `<style>` sont retirées sans avertissement. C'est le comportement attendu : la fonction ne signale pas les suppressions, elle les applique. Un test manuel avec un contenu volontairement corrompu, avant la mise en production, reste indispensable pour vérifier que le résultat correspond aux attentes.

## Corriger les balises non fermées

`wp_kses_post` filtre les balises autorisées, mais ne corrige pas systématiquement une structure mal fermée. Une bibliothèque comme `DOMDocument`, disponible nativement en PHP, permet de reconstruire une arborescence valide avant le filtrage :

```
function reparer_html( string $html ): string {
    $document = new DOMDocument();
    libxml_use_internal_errors( true );
    $document->loadHTML(
        '<div>' . $html . '</div>',
        LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
    );
    libxml_clear_errors();

    return $document->saveHTML( $document->documentElement );
}
```

Cette étape intervient avant `wp_kses_post`, jamais à sa place : réparer une structure ne dispense pas de filtrer son contenu.

## Ne pas oublier les attributs dangereux dans les balises autorisées

Une balise `<a>` autorisée peut malgré tout porter un attribut `onclick` ou un lien `javascript:`. `wp_kses_post` traite déjà ces cas selon sa liste blanche interne, mais toute extension personnalisée de cette liste, via le filtre `wp_kses_allowed_html`, doit être pesée avec la même prudence que la liste d'origine.

- Ne jamais ajouter `on*` aux attributs autorisés d'une balise
- Vérifier que les liens générés pointent vers des domaines de confiance
- Journaliser les contenus rejetés pour repérer les dérives du modèle utilisé

> Un contenu généré n'est ni plus ni moins fiable qu'une saisie de formulaire public : il mérite exactement le même niveau de méfiance avant d'entrer en base.

## Ce qu'il faut retenir

Le nettoyage d'un contenu HTML généré n'est pas une étape optionnelle réservée aux cas suspects : elle fait partie intégrante du traitement, au même titre que l'appel à l'API lui-même. `wp_kses_post`, éventuellement précédé d'une réparation de structure via `DOMDocument`, couvre la grande majorité des besoins d'un site éditorial sans complexité excessive.
