# Le endpoint /wp-json sans authentification : ce qu’il expose par défaut

> Avant tout réglage particulier, une installation WordPress répond déjà publiquement sur plusieurs routes REST. Inventaire de ce qui est visible sans identifiant.

- Auteur : WordPress Développement
- Publié le : 2023-03-23
- Mis à jour le : 2023-03-23
- Catégorie : Headless &amp; API
- URL : https://www.wpmoderne.fr/headless/wp-json-sans-authentification-exposition/

## L’essentiel

- Les routes publiques par défaut couvrent contenus, utilisateurs et réglages
- wp-json/wp/v2/users révèle des identifiants d'utilisateurs par défaut
- Un filtrage explicite reste nécessaire avant toute mise en production

« Cette API a l'air pratique, on va juste requêter `/wp-json/wp/v2/` directement depuis le front. » Cette phrase, prononcée en début de projet, mérite qu'on s'y arrête un instant, car elle sous-entend souvent une méconnaissance de ce que WordPress expose réellement sans le moindre réglage préalable. La documentation officielle sur developer.wordpress.org le précise clairement : la plupart des routes de l'API REST sont accessibles publiquement dès l'activation du cœur, sans qu'aucune authentification ne soit requise pour la lecture.

Pour un développeur qui découvre le développement headless, cette accessibilité par défaut peut sembler être un simple confort. Elle mérite pourtant d'être inventoriée précisément avant toute mise en production, tant certaines routes révèlent des informations que l'équipe éditoriale ne pensait pas rendre publiques.

## Un inventaire simple avec WP-CLI

La commande suivante liste l'ensemble des routes enregistrées sur une installation donnée, avec leurs méthodes disponibles :

```
wp rest-api list 2>/dev/null || curl -s https://exemple.test/wp-json/ | php -r \
  "echo implode(PHP_EOL, array_keys(json_decode(file_get_contents('php://stdin'), true)['routes']));"
```

Sur une installation fraîche, sans extension particulière, cette liste couvre déjà les contenus (`/wp/v2/posts`, `/wp/v2/pages`), les médias, les catégories et étiquettes, les commentaires, et surtout les utilisateurs via `/wp/v2/users`.

## Ce que révèle la route des utilisateurs

C'est souvent la découverte la plus surprenante pour une équipe qui migre vers un usage headless : la route `/wp/v2/users` retourne, sans authentification, la liste des comptes disposant d'au moins un contenu publié, avec leur identifiant numérique, leur pseudonyme public (`slug`) et leur nom affiché. Sur un site où le pseudonyme correspond, par négligence, à l'identifiant de connexion, cette route offre gratuitement la moitié du travail à quiconque cherche à deviner des identifiants valides.

> L'essentiel à retenir : Les routes publiques par défaut couvrent contenus, utilisateurs et réglages ; wp-json/wp/v2/users révèle des identifiants d'utilisateurs par défaut ; Un filtrage explicite reste nécessaire avant toute mise en production

### Le cas des contenus non destinés au public

Les types de contenus personnalisés déclarés avec `show_in_rest => true` héritent, sauf réglage contraire, du même comportement public que les articles standards. Un type de contenu interne, pensé pour un usage strictement administratif, mais exposé par erreur dans l'API, se retrouve accessible à quiconque connaît ou devine son chemin de route.

## Ce qui reste protégé sans intervention

Toutes les routes ne sont pas ouvertes de la même façon. Les opérations d'écriture — création, modification, suppression — restent, elles, correctement protégées par défaut grâce au mécanisme de `permission_callback`, qui vérifie les capacités de l'utilisateur authentifié avant d'autoriser l'action. C'est spécifiquement la lecture qui est permissive par conception, dans une logique historique de compatibilité avec l'affichage public d'un site classique.

| Route | Accès sans authentification | Donnée exposée |
| --- | --- | --- |
| `/wp/v2/posts` | Lecture seule | Contenus publiés |
| `/wp/v2/users` | Lecture seule | Identifiants et pseudonymes publics |
| `/wp/v2/posts` (écriture) | Refusée | Aucune sans jeton valide |
| Types personnalisés | Selon `show_in_rest` | Variable selon déclaration |

## Réduire l'exposition sans tout bloquer

La réponse ne consiste pas à désactiver l'API REST dans son ensemble, ce qui casserait l'éditeur de blocs lui-même, mais à filtrer précisément ce qui doit rester accessible. Le filtre `rest_endpoints` permet de retirer des méthodes sur des routes spécifiques :

```
add_filter( 'rest_endpoints', function ( $endpoints ) {
    if ( isset( $endpoints['/wp/v2/users'] ) ) {
        unset( $endpoints['/wp/v2/users'][0] );
    }
    return $endpoints;
} );
```

Pour un type de contenu personnalisé qui ne doit jamais transiter par l'API publique, il suffit de ne pas déclarer `show_in_rest`, ou de retirer sélectivement la visibilité tout en gardant un accès authentifié via un `permission_callback` personnalisé.

## Les bons réflexes avant mise en production

- Lister systématiquement les routes exposées avant chaque mise en ligne, pas seulement lors de l'audit initial du projet.
- Vérifier le contenu exact retourné par `/wp/v2/users` et masquer les champs superflus via `register_rest_field()` si nécessaire.
- Documenter, pour chaque type personnalisé, la décision explicite d'exposition ou non dans l'API REST.

> Une route publique par défaut n'est pas une faille en soi : c'est un choix de conception hérité de l'histoire de WordPress. Le problème apparaît quand personne dans l'équipe n'a vérifié ce que ce choix implique concrètement pour le projet en cours.

## En résumé

Avant d'écrire la moindre ligne de code côté front, un inventaire des routes exposées par défaut évite bien des mauvaises surprises. Ce réflexe, simple à mettre en place avec WP-CLI ou un appel direct à `/wp-json/`, mérite de figurer systématiquement dans la checklist de démarrage de tout projet headless.
