Le WordPress d'aujourd'hui, décodé pour les développeurs

Sécurité

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.

Par WordPress Développement • 8 juin 2023 • 4 min de lecture • Aucun commentaire
Exposer un champ meta sensible par défaut via register_meta

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érificationMéthode
Lister les champs exposésRequête anonyme sur /wp-json/wp/v2/{type}/{id}
Identifier l’origine de chaque champRecherche de register_meta dans le code des extensions
Vérifier la présence d’un auth_callbackLecture 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é.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi