# Repérer une marge affichée par erreur sur une fiche produit industrielle

> Un champ de calcul interne s'est retrouvé exposé publiquement sur des fiches produit d'un fabricant B2B. Retour sur le diagnostic d'un gabarit qui affichait un champ destiné à l'administration.

- Auteur : Clément Hadrot
- Publié le : 2025-05-25
- Mis à jour le : 2025-05-25
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/marge-affichee-erreur-fiche-produit-industrielle/

## L’essentiel

- Le champ n'était jamais censé quitter l'administration
- Le gabarit bouclait sur tous les champs personnalisés sans liste blanche
- La correction passe par une liste explicite de champs autorisés à l'affichage

« Marge : 34 % » affiché en toutes lettres sous la référence d'un roulement industriel, sur la fiche produit publique d'un fabricant spécialisé dans les composants mécaniques pour l'agroalimentaire. Le champ n'avait strictement rien à faire sur cette page : il servait uniquement au service commercial interne, pour calculer rapidement une remise possible sans dévoiler la logique de tarification au client final.

Le signalement venait d'un client qui avait consulté le code source de la page par curiosité technique, avant de contacter l'équipe commerciale pour demander pourquoi sa marge de négociation semblait déjà connue d'avance. Voici comment ce diagnostic s'est déroulé, du symptôme jusqu'à la correction.

## Symptôme : un champ interne visible dans le code source

Le champ `marge_calculee` apparaissait dans une balise `<meta>` personnalisée, générée automatiquement par une fonction censée exposer des informations utiles au référencement. Rien dans l'affichage visuel de la page ne montrait ce champ : seul un examen du code source HTML le révélait, ce qui explique pourquoi le problème était passé inaperçu pendant plusieurs mois.

```
<meta name="ch-produit-marge_calculee" content="34" />
<meta name="ch-produit-reference_fournisseur" content="RLM-2201-B" />
<meta name="ch-produit-cout_revient" content="128.50" />
```

## Diagnostic : une boucle générique sans liste blanche

La fonction responsable de cette exposition parcourait **tous** les champs personnalisés du produit, sans distinction entre ce qui était destiné à un usage interne et ce qui pouvait raisonnablement être exposé publiquement. Un développeur précédent avait ajouté cette boucle pour un besoin ponctuel de référencement, sans anticiper que de nouveaux champs internes viendraient s'y ajouter par la suite.

```
// Code fautif : aucune liste blanche, tout est exposé
add_action( 'wp_head', function () {
    if ( ! is_singular( 'produit' ) ) {
        return;
    }
    $champs = get_post_meta( get_the_ID() );
    foreach ( $champs as $cle => $valeurs ) {
        printf( '<meta name="ch-produit-%s" content="%s" />' . "\n", esc_attr( $cle ), esc_attr( $valeurs[0] ) );
    }
} );
```

> L'essentiel à retenir : Le champ n'était jamais censé quitter l'administration ; Le gabarit bouclait sur tous les champs personnalisés sans liste blanche ; La correction passe par une liste explicite de champs autorisés à l'affichage

## Correctif : une liste explicite de champs autorisés

La correction remplace la boucle ouverte par une liste blanche fermée, qui énumère précisément les six champs autorisés à quitter l'administration. Tout nouveau champ interne créé par la suite reste protégé par défaut, puisqu'il faudra l'ajouter explicitement à cette liste pour qu'il devienne visible.

```
add_action( 'wp_head', function () {
    if ( ! is_singular( 'produit' ) ) {
        return;
    }

    $champs_publics = array(
        'reference_produit',
        'poids_kg',
        'materiau',
        'norme_conformite',
        'delai_fabrication',
        'garantie_mois',
    );

    foreach ( $champs_publics as $cle ) {
        $valeur = get_post_meta( get_the_ID(), $cle, true );
        if ( '' !== $valeur ) {
            printf( '<meta name="ch-produit-%s" content="%s" />' . "\n", esc_attr( $cle ), esc_attr( $valeur ) );
        }
    }
} );
```

## Prévention : nommer les champs internes sans ambiguïté

Au-delà de la correction immédiate, l'équipe a adopté une convention de nommage qui rend une erreur future plus difficile à commettre silencieusement : tout champ strictement interne commence désormais par le préfixe `_interne_`, un préfixe qui, combiné à une vérification systématique, exclut automatiquement ces champs de toute boucle générique future.

- Renommage de `marge_calculee` en `_interne_marge_calculee`, avec migration des données existantes par une commande WP-CLI dédiée.
- Ajout d'une vérification systématique `strpos( $cle, '_interne_' ) === 0` dans toute fonction générique qui parcourt les champs personnalisés d'un produit.
- Revue de toutes les boucles similaires sur le site, un exercice qui a permis de trouver deux autres cas d'exposition moins sensibles mais tout aussi injustifiés.

### Vérifier qu'aucune autre fonction ne reproduit l'erreur

Une recherche du terme `get_post_meta( $champs )` sans clé précise, dans l'ensemble du thème et des extensions maison, a permis de repérer les autres endroits susceptibles de reproduire le même schéma. C'est une vérification qui mérite d'être répétée après chaque intervention d'un nouveau développeur sur un projet ancien.

> Une boucle générique sur des champs personnalisés est pratique à écrire, mais elle expose tout ce qu'on y ajoutera plus tard sans y penser : la liste blanche protège contre l'oubli futur, pas seulement contre l'erreur présente.

## En résumé

Ce cas illustre un piège fréquent : une fonction écrite pour un besoin ponctuel et légitime devient, avec le temps et l'ajout de nouveaux champs, une source d'exposition qui n'a jamais été revue. Ce diagnostic ne traite volontairement pas le calcul de marge lui-même, question purement commerciale, mais uniquement la façon dont cette information avait fini par fuiter d'un usage interne vers l'affichage public.
