# « alert(1) » dans un devis BTP : quand un champ commentaire libre exécute du script

> Un artisan du bâtiment découvre qu'un champ de commentaire libre de son formulaire de devis permettait d'injecter du script exécuté dans l'interface d'administration.

- Auteur : Clément Hadrot
- Publié le : 2022-04-15
- Mis à jour le : 2022-04-15
- Catégorie : Sécurité
- URL : https://wpmoderne.dev.wordpress-developpement.fr/securite/formulaire-devis-btp-script-champ-libre/

## L’essentiel

- Un champ libre affiché sans échappement devient un vecteur d'attaque
- La faille touche l'administration, pas seulement le site public
- La correction combine sanitisation en entrée et échappement en sortie

« alert(1) » : c'est le contenu, volontairement anodin, d'une balise `<script>` retrouvée dans le champ commentaire d'un devis soumis via le formulaire du site vitrine d'un artisan du bâtiment. Cette balise, une fois le devis consulté dans l'espace d'administration WordPress, déclenchait une fenêtre d'alerte JavaScript, preuve suffisante qu'un contenu bien plus malveillant qu'une simple alerte aurait pu s'exécuter à la place, dans le contexte authentifié de l'administrateur du site.

La conception générale du formulaire de devis, ses champs, sa mise en page, ne fait pas l'objet de cet article : le point précis qui a posé problème est le traitement du champ « précisions complémentaires », un simple textarea destiné à recueillir des informations libres du client (accès au chantier, contraintes horaires, détails du projet), affiché tel quel dans l'interface d'administration sans aucun traitement d'échappement.

## Comment la faille a été découverte

Un client, testant lui-même le formulaire avant de le recommander à un confrère, avait saisi par curiosité une balise de test dans le champ commentaire. Ce n'était pas une tentative malveillante : simplement un réflexe de développeur amateur qui voulait vérifier ce qui se passerait. Le résultat, une alerte JavaScript apparue dans le tableau de bord de l'artisan lors de la consultation du devis, a immédiatement révélé le problème, sans qu'aucun outil d'audit sophistiqué n'ait été nécessaire.

## Ce que cette faille XSS stockée rendait possible

> L'essentiel à retenir : Un champ libre affiché sans échappement devient un vecteur d'attaque ; La faille touche l'administration, pas seulement le site public ; La correction combine sanitisation en entrée et échappement en sortie

Une injection de script dans un champ affiché à l'administrateur s'exécute dans le contexte de sa session authentifiée. Un contenu malveillant, à la place de la simple alerte de test, aurait pu créer un nouvel utilisateur administrateur à l'insu de l'artisan, modifier le contenu du site, ou exfiltrer le cookie de session vers un serveur tiers, le tout déclenché par la simple consultation d'un devis dans le tableau de bord, sans aucune action suspecte apparente de la part de l'administrateur lui-même.

## La cause : un affichage sans échappement

```
// Avant correction, dans le template d'administration :
echo '<div class="commentaire-client">' . $devis['commentaire'] . '</div>';
```

Le contenu du champ était inséré directement dans le HTML de la page d'administration, sans passer par une fonction d'échappement adaptée au contexte d'affichage.

## La correction : sanitiser en entrée, échapper en sortie

```
// À la réception du formulaire :
$commentaire = sanitize_textarea_field( $_POST['commentaire'] );

// À l'affichage dans l'administration :
echo '<div class="commentaire-client">' . esc_html( $commentaire ) . '</div>';
```

`sanitize_textarea_field()` nettoie le contenu à la réception, en retirant les balises et en normalisant les sauts de ligne, tandis que `esc_html()` échappe systématiquement tout caractère spécial au moment de l'affichage, quel que soit le contenu réellement stocké en base. Cette double protection reste efficace même si un contenu malveillant parvenait, par un autre biais, à contourner la première étape.

### Ne pas oublier les autres points d'affichage du même champ

Le même champ commentaire était également repris dans l'email de notification envoyé à l'artisan à chaque nouveau devis, et dans un export PDF généré à la demande. Chacun de ces points d'affichage a dû être vérifié individuellement : un champ correctement échappé dans l'administration mais oublié dans le template d'email aurait laissé la faille active par un autre canal.

## Vérifier l'ensemble des formulaires du site après un tel incident

- Recenser tous les champs de texte libre affichés côté administration.
- Vérifier que chacun passe par une fonction d'échappement adaptée au contexte (HTML, attribut, JavaScript).
- Tester chaque champ avec une balise de test inoffensive, comme celle découverte ici par hasard.

> Un champ de commentaire libre, aussi anodin qu'il paraisse, est un formulaire d'entrée comme un autre : il mérite le même traitement d'échappement que n'importe quel autre point de saisie du site.

## En résumé

Cette faille, découverte par hasard et sans intention malveillante, aurait pu avoir des conséquences bien plus lourdes qu'une simple fenêtre d'alerte. La correction, une sanitisation en entrée combinée à un échappement systématique en sortie, illustre un principe qui devrait s'appliquer à chaque champ de texte libre d'un formulaire, quelle que soit son importance apparente.
