# Sanitisation contre échappement : un test qui vérifie qu’on ne confond rien

> Nettoyer en entrée et échapper en sortie ne sont pas interchangeables. Un test dédié verrouille cette discipline plutôt que de la laisser reposer sur la seule vigilance humaine.

- Auteur : WordPress Développement
- Publié le : 2024-05-18
- Mis à jour le : 2024-05-18
- Catégorie : Tests
- URL : https://www.wpmoderne.fr/tests/sanitisation-echappement-test-verifie-pas-confondu/

## L’essentiel

- Nettoyer une donnée en entrée protège le stockage, échapper protège l'affichage
- Les deux opérations répondent à des menaces différentes et ne se substituent jamais l'une à l'autre
- Un test peut verrouiller qu'une valeur brute stockée n'a jamais été échappée trop tôt

« Nettoyé une fois, échappé une fois, jamais l'inverse » : cette règle tient en une phrase, mais son respect dans une extension publique maintenue par plusieurs contributeurs sur la durée ne tient pas qu'à la bonne volonté de chacun. Un test dédié transforme cette discipline en garantie vérifiée automatiquement, plutôt qu'en convention qu'une revue de code peut laisser passer.

Ce sujet ne détaille pas le fonctionnement interne de `wp_kses()` ni des fonctions d'échappement elles-mêmes, supposées déjà connues : il porte sur la façon de verrouiller, par un test, que ces deux opérations restent bien à leur place respective dans le cycle de vie d'une donnée.

## Deux menaces différentes, deux réponses différentes

Nettoyer une donnée en entrée protège contre ce qui serait stocké de façon dangereuse ou incohérente : un champ censé contenir un nombre qui reçoit du balisage HTML, une chaîne trop longue pour la colonne de base de données visée. Échapper une donnée en sortie protège contre ce que l'affichage pourrait exécuter ou interpréter à tort : un script injecté qui s'exécuterait dans le navigateur d'un visiteur si la donnée était affichée telle quelle.

Confondre les deux mène à deux erreurs symétriques, aussi dommageables l'une que l'autre : échapper une donnée avant de la stocker corrompt la valeur d'origine, qui apparaît alors avec des entités HTML littérales partout où elle est utilisée en dehors d'un contexte d'affichage ; ne jamais échapper une donnée à l'affichage, en se fiant uniquement à la sanitisation d'entrée, laisse une ouverture si la donnée provient d'une source qui a contourné cette étape (import, migration, appel direct à la base de données).

## Le test qui verrouille l'ordre des opérations

L'idée du test consiste à vérifier, sur une valeur volontairement problématique, que la donnée stockée reste brute (non échappée), tandis que la donnée affichée est bien échappée au moment du rendu :

```
class SanitisationEchappementTest extends WP_UnitTestCase
{
    public function test_la_valeur_stockee_reste_brute(): void
    {
        $idArticle = self::factory()->post->create();
        update_post_meta($idArticle, 'sous_titre', 'Offre <b>spéciale</b>');

        $valeurBrute = get_post_meta($idArticle, 'sous_titre', true);

        $this->assertSame('Offre <b>spéciale</b>', $valeurBrute);
    }

    public function test_laffichage_echappe_la_meme_valeur(): void
    {
        $idArticle = self::factory()->post->create();
        update_post_meta($idArticle, 'sous_titre', 'Offre <b>spéciale</b>');

        $sortieAffichee = afficher_sous_titre($idArticle);

        $this->assertStringContainsString('&lt;b&gt;', $sortieAffichee);
    }
}
```

> L'essentiel à retenir : Nettoyer une donnée en entrée protège le stockage, échapper protège l'affichage ; Les deux opérations répondent à des menaces différentes et ne se substituent jamais l'une à l'autre ; Un test peut verrouiller qu'une valeur brute stockée n'a jamais été échappée trop tôt

Ces deux tests, pris ensemble, verrouillent une contrainte que la revue de code seule ne peut pas garantir dans la durée : la valeur brute reste inchangée en base, et c'est uniquement au moment de l'affichage que l'échappement intervient. Si un futur contributeur déplace par erreur l'échappement vers la fonction de sauvegarde, le premier test échoue immédiatement.

## Étendre le test aux points d'entrée alternatifs

Une extension publique reçoit rarement ses données par un seul chemin. Un import CSV, une API REST personnalisée ou une synchronisation avec un service tiers peuvent contourner le formulaire d'origine et ainsi le point où la sanitisation d'entrée est habituellement appliquée. Le même test, dupliqué pour chaque point d'entrée alternatif identifié, révèle si l'un d'eux oublie la sanitisation que les autres appliquent correctement.

- Point d'entrée du formulaire d'administration standard.
- Point d'entrée d'un éventuel import en masse.
- Point d'entrée d'une route REST personnalisée qui accepte la même donnée.

## En résumé

Un test qui vérifie séparément qu'une valeur reste brute en stockage et qu'elle est bien échappée à l'affichage transforme une règle de bonne pratique en garantie automatisée, résistante aux changements de contributeurs sur la durée de vie d'une extension publique. Répéter ce test pour chaque point d'entrée alternatif de la même donnée referme une source d'incohérence facile à manquer en revue de code seule.
