vendredi 25 septembre 2026

À propos

Contact

Headless & API

Filtrer les champs sensibles exposés par /wp/v2/users en headless

Le point de terminaison des utilisateurs révèle par défaut plus d'informations qu'un front headless ne devrait afficher publiquement. Recette pour restreindre le contexte et masquer l'email.

Par Clément Hadrot • 17 janvier 2021 • 4 min de lecture • Aucun commentaire
Filtrer les champs sensibles exposés par /wp/v2/users en headless

Un audit rapide chez un nouveau client nous a mis la puce à l’oreille début janvier : son front headless affichait, sans le vouloir, le lien vers l’archive des articles d’un auteur qui n’existait plus que dans la base WordPress, ainsi qu’un champ d’URL personnel jamais renseigné volontairement pour un usage public. Le point de terminaison /wp-json/wp/v2/users, consulté depuis les articles pour afficher le nom de l’auteur, en révélait bien plus que nécessaire.

Cette recette ne traite pas de l’énumération des utilisateurs par force brute, un sujet de sécurité déjà couvert ailleurs sur ce blog. Elle porte spécifiquement sur ce qu’un front headless choisit d’afficher, et sur la manière de couper court à ce qui ne devrait jamais sortir en clair.

Ce que révèle le contexte view par défaut

Sans authentification, l’API REST limite déjà une partie des champs utilisateur au contexte view plutôt qu’edit : l’adresse email brute n’apparaît pas telle quelle dans la réponse standard d’un appel anonyme, contrairement à une idée reçue. En revanche, des champs comme url, description, link (l’archive des articles de l’auteur) et un avatar_urls pointant vers Gravatar restent bien présents, avec parfois plus de détails qu’un front public ne devrait relayer.

curl -s https://exemple.fr/wp-json/wp/v2/users/3 | jq
{
  "id": 3,
  "name": "Julie Fontaine",
  "url": "",
  "description": "Ancienne stagiaire, compte jamais désactivé",
  "link": "https://exemple.fr/author/julie-fontaine/",
  "slug": "julie-fontaine",
  "avatar_urls": { "24": "...", "48": "...", "96": "..." }
}

Restreindre l’exposition avec rest_prepare_user

Le filtre natif rest_prepare_user permet de retirer, au vol, tout champ jugé non pertinent avant que la réponse ne parte du serveur :

add_filter( 'rest_prepare_user', function ( $response, $user, $request ) {
    $data = $response->get_data();

    unset( $data['url'] );
    unset( $data['description'] );
    unset( $data['avatar_urls'] );

    // On garde uniquement ce dont un front a réellement besoin :
    $response->set_data( array(
        'id'   => $data['id'],
        'name' => $data['name'],
        'slug' => $data['slug'],
        'link' => $data['link'],
    ) );

    return $response;
}, 10, 3 );
L'essentiel à retenir : Le contexte view expose déjà des données à filtrer ; rest_prepare_user retire les clés indésirables ; Le nom d'affichage suffit dans la grande majorité des cas

Le cas des comptes désactivés ou obsolètes

Le point de terminaison /wp-json/wp/v2/users continue de lister tout utilisateur ayant publié au moins un article, même un compte d’ancien collaborateur jamais supprimé. Pour un front qui n’a besoin que des auteurs actifs, il est possible de filtrer la liste elle-même avec rest_user_query, en imposant par exemple un rôle minimal :

add_filter( 'rest_user_query', function ( $args, $request ) {
    $args['role__in'] = array( 'author', 'editor', 'administrator' );
    return $args;
}, 10, 2 );

Ce filtre n’empêche pas de retrouver un article déjà publié par un ancien compte, mais évite que ce compte n’apparaisse dans une liste d’auteurs proposée par le front, par exemple pour un filtre de recherche par rédacteur.

Faut-il aller jusqu’à masquer l’email ?

Par défaut, le champ email n’est déjà retourné qu’en contexte edit, réservé aux comptes authentifiés avec la capacité list_users. Un front headless anonyme ne devrait donc jamais le recevoir. La véritable vigilance porte plutôt sur les intégrations tierces : un plugin de formulaire ou un module de commentaires mal configuré peut, lui, demander le contexte edit avec des identifiants trop larges, et exposer l’email par un chemin détourné. Vérifier régulièrement les rôles et capacités des comptes utilisés par les intégrations reste la meilleure protection.

Vérifier le résultat après coup

  • Comparer une réponse avant et après le filtre avec curl, pour confirmer que seuls les champs voulus restent présents.
  • Contrôler que la liste /wp-json/wp/v2/users ne renvoie plus de comptes désactivés ou sans rôle éditorial actif.
  • Tester également le point de terminaison embed utilisé par les articles (_embedded.author), qui applique le même filtre mais mérite une vérification séparée.

Un compte utilisateur WordPress n’a jamais été pensé pour un affichage public complet : c’est un profil d’administration avant tout, et un front headless doit le traiter comme une ressource à filtrer, pas à recopier telle quelle.

En résumé

Le point de terminaison des utilisateurs mérite le même traitement que n’importe quelle autre ressource sensible de l’API REST : un filtre explicite, appliqué en connaissance de cause, plutôt qu’une confiance aveugle dans les réglages par défaut. Quelques lignes suffisent pour ramener la réponse à l’essentiel : un nom, un identifiant, un lien vers l’archive de l’auteur, rien de plus.

Partager :

À propos de l'auteur

Clément Hadrot

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

Voir tous ses articles

Dans la même veine

À lire aussi