register_meta( 'post', 'montant_negocie', array( 'show_in_rest' => true, 'single' => true, 'type' => 'number' ) ) : cette déclaration, trouvée telle quelle dans une extension métier sur mesure, suffisait à rendre un montant commercial confidentiel consultable par n’importe quel visiteur non authentifié, via la réponse standard de l’API REST WordPress.
L’audit portait sur un site vitrine doublé d’un espace de gestion d’appels d’offres, où chaque article représentait un dossier commercial. Le champ montant_negocie, réservé à un usage interne visible uniquement dans l’éditeur de contenu, n’était protégé par aucune restriction de rôle au niveau de l’API.
Ce qu’on observe
Une simple requête vers /wp-json/wp/v2/posts/482, sans en-tête d’authentification, retournait l’intégralité des champs meta déclarés avec show_in_rest à true, dans la clé meta de la réponse JSON. Le montant négocié, destiné exclusivement à l’équipe commerciale, figurait au même niveau de visibilité que le titre ou l’extrait de l’article.
{
"id": 482,
"title": { "rendered": "Appel d'offres - Rénovation site A" },
"meta": {
"montant_negocie": 184500,
"reference_interne": "AO-2023-0482"
}
}
Aucune erreur, aucun avertissement dans les journaux : le comportement correspondait exactement à ce que register_meta avait été configuré pour faire. Le défaut ne résidait pas dans un bug, mais dans une hypothèse implicite jamais vérifiée par l’équipe de développement.
Pourquoi c’est un problème
Le paramètre show_in_rest détermine si un champ meta apparaît dans les réponses de l’API REST, indépendamment de sa visibilité dans l’interface d’administration. Ces deux notions de visibilité — administrative et publique — sont totalement indépendantes l’une de l’autre dans l’architecture de WordPress, ce qui constitue précisément la source de la confusion la plus fréquente sur ce sujet.
- Un champ visible uniquement pour les rédacteurs dans l’éditeur peut, si
show_in_restest actif, devenir public par la même occasion. - La documentation officielle sur developer.wordpress.org précise que
show_in_restpeut recevoir un tableau de configuration détaillé, pas seulement un booléen. - Sans restriction supplémentaire, la valeur par défaut expose le champ à toute requête, authentifiée ou non.

Quoi faire à la place
Restreindre la lecture d’un champ meta sensible ne demande pas de renoncer à son exposition dans l’API pour les usages internes qui en ont besoin, par exemple un tableau de bord interne consommant cette même API. La configuration détaillée de show_in_rest permet de conditionner explicitement la visibilité du champ à une vérification de capacité.
register_meta( 'post', 'montant_negocie', array(
'single' => true,
'type' => 'number',
'show_in_rest' => array(
'schema' => array(
'type' => 'number',
),
),
'auth_callback' => function () {
return current_user_can( 'gerer_appels_offres' );
},
) );
La fonction auth_callback conditionne la lecture comme l’écriture du champ à une capacité précise, sans retirer show_in_rest et donc sans priver les outils internes autorisés de cet accès via l’API. Ce point n’est volontairement pas approfondi ici sous l’angle du paramètre permission_callback d’une route personnalisée, déjà largement documenté par ailleurs : il s’agit ici spécifiquement du comportement propre à register_meta pour les champs attachés aux types de contenus existants.
Un audit simple à reproduire
Repérer ce type d’exposition ne demande aucun outil spécialisé : une requête anonyme vers l’API REST d’un type de contenu, comparée à la liste des champs personnalisés déclarés dans le code de chaque extension active, suffit à révéler tout champ visible sans justification métier claire.
| Vérification | Méthode |
|---|---|
| Lister les champs exposés | Requête anonyme sur /wp-json/wp/v2/{type}/{id} |
| Identifier l’origine de chaque champ | Recherche de register_meta dans le code des extensions |
| Vérifier la présence d’un auth_callback | Lecture du tableau show_in_rest déclaré |
Repère retenu de cet audit :
show_in_restrépond à la question « ce champ doit-il exister dans l’API ? », jamais à la question « qui a le droit de le lire ? ». Confondre les deux est l’erreur la plus commune sur ce point précis.
En résumé
Un champ meta sensible ne devient dangereux que lorsqu’il devient public par un paramètre technique dont l’effet réel dépasse l’intention de départ. La vigilance à avoir porte moins sur la présence de show_in_rest que sur l’absence, à chaque fois qu’un champ transporte une information qui ne devrait pas quitter l’équipe qui la manipule, d’un contrôle d’accès explicite associé.