1 800 biens d’un catalogue immobilier récupérés en une seule minute, avec un script de quelques lignes utilisant la pagination native de l’API : c’est le test qu’a mené un développeur mandaté pour un audit de sécurité léger chez une agence immobilière, avant même de chercher une vraie faille. L’API REST ouverte n’en avait pas besoin, elle donnait tout sans qu’on le lui demande poliment, faute de la moindre limite de débit.
La conception du catalogue lui-même (structure des biens, champs affichés, logique de recherche) ne fait pas l’objet de ce tutoriel. Le sujet ici est plus étroit et plus urgent : cette API, exposée pour alimenter un widget de recherche intégré sur le site, était accessible sans authentification, sans restriction d’origine, et sans aucune limite de débit, ce qui en faisait une cible évidente pour n’importe quel concurrent souhaitant reproduire le catalogue ailleurs, ou pour un simple robot d’aspiration massive.
Étape 1 : mesurer l’exposition réelle avant de corriger
Avant toute correction, il faut établir un état des lieux précis. Un simple appel permet de vérifier ce qui est retourné sans en-tête d’authentification :
curl -s https://agence-exemple.fr/wp-json/wp/v2/biens?per_page=100&page=1 | jq length
Sur ce site, la réponse retournait cent résultats par page, sans plafond global appliqué au nombre de requêtes successives, permettant de parcourir les dix-huit pages nécessaires en quelques secondes.
Étape 2 : distinguer les champs réellement publics des champs internes

Comme souvent sur ce type de catalogue, certains champs (nom du mandataire interne, commission de l’agence, date d’entrée en mandat) n’avaient aucune raison de figurer dans une réponse publique. Un filtre sur rest_prepare_bien retire ces champs avant l’envoi de la réponse, indépendamment de toute autre mesure de protection.
Étape 3 : appliquer une limite de débit par adresse IP
WordPress ne propose pas de limitation de débit native sur les routes REST personnalisées. Elle s’implémente via un compteur stocké en cache objet ou en transient, incrémenté à chaque appel :
function verifier_limite_debit( $request ) {
$ip = $_SERVER['REMOTE_ADDR'];
$cle = 'rl_' . md5( $ip );
$compteur = (int) get_transient( $cle );
if ( $compteur >= 60 ) {
return new WP_Error( 'trop_de_requetes', 'Limite de débit atteinte', array( 'status' => 429 ) );
}
set_transient( $cle, $compteur + 1, MINUTE_IN_SECONDS );
return true;
}
Ce garde-fou, réglé à soixante requêtes par minute et par IP, laisse largement de la marge pour un usage normal du widget de recherche, tout en rendant l’aspiration massive du catalogue beaucoup plus lente et coûteuse pour qui s’y risquerait.
Étape 4 : restreindre l’origine des requêtes côté navigateur
Le widget de recherche n’a besoin d’être appelé que depuis le domaine de l’agence lui-même. Un en-tête CORS restrictif limite les appels effectués directement depuis le navigateur d’un autre site :
add_filter( 'rest_pre_serve_request', function( $served, $result, $request ) {
header( 'Access-Control-Allow-Origin: https://agence-exemple.fr' );
return $served;
}, 10, 3 );
Cette restriction ne bloque pas un script exécuté côté serveur par un tiers, qui n’est pas soumis à la politique CORS du navigateur : elle complète la limitation de débit, elle ne la remplace pas.
Étape 5 : prévoir un accès distinct pour les vrais partenaires
Certains partenaires légitimes (portails immobiliers, comparateurs) ont besoin d’un accès plus large que le grand public. Plutôt que d’ouvrir l’API à tous pour les satisfaire, un jeton d’application dédié, vérifié dans le permission_callback, leur accorde un quota plus généreux sans exposer le catalogue entier à quiconque.
Une API ouverte sans aucune limite n’est jamais un simple confort technique : elle transforme chaque visiteur, bienveillant ou non, en capacité potentielle d’aspirer l’intégralité du catalogue en quelques minutes.
En résumé
Fermer l’accès anonyme d’une API REST ne signifie pas nécessairement exiger une authentification partout : cela commence par retirer les champs internes, limiter le débit par adresse IP, restreindre l’origine côté navigateur, et réserver un accès élargi aux partenaires identifiés. Sur ce catalogue, ces quatre mesures combinées ont fait passer le temps d’aspiration complet de moins d’une minute à plusieurs heures, un ordre de grandeur qui change tout.