# Exposer un champ meta sensible par défaut via register_meta

> Un champ personnalisé jamais destiné au public apparaissait pourtant en clair dans chaque réponse de l'API REST, faute d'un contrôle explicite.

- Auteur : WordPress Développement
- Publié le : 2023-06-08
- Mis à jour le : 2023-06-08
- Catégorie : Sécurité
- URL : https://www.wpmoderne.fr/securite/exposer-champ-meta-sensible-register-meta/

## L’essentiel

- show_in_rest à true expose le champ dans les réponses publiques par défaut
- Un champ visible dans l'administration n'est pas censé être visible publiquement
- auth_callback permet de restreindre la lecture sans retirer show_in_rest

`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_rest` est actif, devenir public par la même occasion.
- La documentation officielle sur developer.wordpress.org précise que `show_in_rest` peut 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.

> L'essentiel à retenir : show_in_rest à true expose le champ dans les réponses publiques par défaut ; Un champ visible dans l'administration n'est pas censé être visible publiquement ; auth_callback permet de restreindre la lecture sans retirer show_in_rest

## 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_rest` ré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é.
