# Une taxonomie privée expose par défaut son contenu via l’API REST sans permission_callback dédié

> Activer show_in_rest sur une taxonomie interne ne la rend pas privée pour autant. Comprendre pourquoi, et comment fermer l'accès correctement.

- Auteur : WordPress Développement
- Publié le : 2023-03-08
- Mis à jour le : 2023-03-08
- Catégorie : Sécurité
- URL : https://www.wpmoderne.fr/securite/taxonomie-privee-api-rest-permission-callback/

## L’essentiel

- show_in_rest expose la route sans vérifier qui la consulte
- Le contrôle d'accès doit être ajouté explicitement
- Une taxonomie interne n'a souvent pas besoin d'une route REST du tout

D'après la documentation officielle des routes REST de taxonomie sur developer.wordpress.org, un argument `show_in_rest: true` passé à `register_taxonomy()` enregistre automatiquement une route `/wp/v2/<taxonomie>` accessible en lecture, sans authentification requise par défaut. Ce comportement est documenté, mais il surprend régulièrement les développeurs qui pensaient qu'une taxonomie non listée dans les menus d'administration restait de fait invisible pour le public.

Le cas typique concerne une taxonomie créée pour un usage purement interne : classification de partenaires par niveau de confidentialité, statut de traitement d'un dossier, segment commercial attribué à un contenu. Ces termes n'apparaissent nulle part dans l'interface publique du site, mais restent parfaitement consultables via l'API REST dès que `show_in_rest` est activé, ce qui est souvent fait par réflexe pour permettre leur usage dans l'éditeur de blocs.

## Pourquoi la route reste ouverte

Le paramètre `show_in_rest` contrôle uniquement l'enregistrement de la route ; il ne configure aucune restriction d'accès. La fonction interne `rest_ensure_response()` utilisée par le contrôleur `WP_REST_Terms_Controller` renvoie les termes correspondants sans filtrage de visibilité particulier, en s'appuyant sur les mêmes règles de permission par défaut que les taxonomies publiques comme les catégories ou les étiquettes.

Concrètement, une requête `GET /wp-json/wp/v2/niveau-confidentialite` renverra la liste complète des termes de cette taxonomie à n'importe quel visiteur non authentifié, y compris ceux jamais utilisés sur un contenu publié — un problème distinct mais lié, puisque même un terme « orphelin » reste listé.

## Fermer l'accès avec un permission_callback dédié

La correction consiste à intervenir sur les arguments de la route au moment de l'enregistrement de la taxonomie, via le tableau `rest_controller_class` ou plus simplement en filtrant la réponse. La méthode la plus directe reste de définir `show_in_rest` à `false` si la taxonomie n'a réellement aucun besoin d'exposition, et de gérer son usage dans l'éditeur via un champ personnalisé ou un panneau latéral construit avec l'API `@wordpress/data` plutôt que la route REST native.

> L'essentiel à retenir : show_in_rest expose la route sans vérifier qui la consulte ; Le contrôle d'accès doit être ajouté explicitement ; Une taxonomie interne n'a souvent pas besoin d'une route REST du tout

Quand une route REST reste nécessaire — par exemple pour un usage interne via une application connectée avec un compte de service — la restriction s'ajoute via le filtre `rest_endpoints` :

```
add_filter( 'rest_endpoints', function ( $endpoints ) {
    $route = '/wp/v2/niveau-confidentialite';
    if ( isset( $endpoints[ $route ] ) ) {
        foreach ( $endpoints[ $route ] as &$handler ) {
            $handler['permission_callback'] = function () {
                return current_user_can( 'manage_options' );
            };
        }
    }
    return $endpoints;
} );
```

## Une alternative plus propre : ne pas passer par show_in_rest

Pour une taxonomie strictement interne, la solution la plus sûre reste souvent de ne jamais l'exposer à l'API REST publique, et de construire l'interface d'édition nécessaire via des hooks d'administration classiques (`meta_box`, `quick_edit_custom_box`) plutôt que via l'éditeur de blocs. Cela réduit la surface d'attaque à zéro pour cette taxonomie, sans compromis à gérer sur les permissions.

- Taxonomie utilisée uniquement en back-office : `show_in_rest => false`
- Taxonomie nécessaire dans l'éditeur de blocs, mais réservée à certains rôles : route REST avec `permission_callback` strict
- Taxonomie destinée à être publique : aucun changement nécessaire

## Vérifier ce qui est déjà exposé sur un projet existant

Un audit rapide consiste à lister les taxonomies enregistrées avec `get_taxonomies( array(), 'objects' )` et à vérifier la propriété `show_in_rest` de chacune, en la croisant avec son usage réel prévu. Sur plusieurs projets audités, il n'était pas rare de trouver deux à trois taxonomies internes exposées sans qu'aucun besoin front-end ne le justifie, restes d'une configuration copiée d'un projet précédent.

> Une route REST ouverte par défaut n'est pas une faille de WordPress ; c'est une configuration à valider explicitement, taxonomie par taxonomie.

## En résumé

Une taxonomie privée ne l'est jamais automatiquement dès qu'elle est exposée à l'API REST : `show_in_rest` ouvre une route consultable sans authentification, indépendamment de sa visibilité dans l'administration. Le réflexe à adopter consiste à se demander, pour chaque taxonomie interne, si l'exposition REST est réellement nécessaire, et à restreindre l'accès explicitement avec un `permission_callback` quand elle l'est.
