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

Sécurité

La clé d’API d’un service météo agricole exposée dans un thème viticole

Un widget météo affiché sur un site de domaine viticole embarquait sa clé d'API en clair dans le thème, visible de tout visiteur curieux.

Par Clément Hadrot • 5 décembre 2024 • 4 min de lecture • Aucun commentaire
La clé d'API d'un service météo agricole exposée dans un thème viticole

view-source: — c’est la seule commande nécessaire pour trouver la clé d’API d’un service météo agricole intégrée à un thème viticole personnalisé. Le widget affichait les prévisions de gel et de précipitations sur la page d’accueil du domaine, une fonctionnalité appréciée des visiteurs et utile pour planifier les visites de la propriété. Mais la clé qui interrogeait le service météo tiers était écrite directement dans un fichier JavaScript chargé publiquement.

Ce type de fuite ne vient presque jamais d’une intention négligente : un développeur teste rapidement une intégration, oublie de déplacer la clé côté serveur, et le code part en production tel quel. La suite de cet article ne traite pas de la migration générale des clés vers des variables d’environnement, déjà documentée ailleurs : il se concentre sur ce cas précis et sur le correctif immédiat.

Comment la fuite a été repérée

Le domaine a reçu une notification du fournisseur météo signalant un usage anormalement élevé de son quota d’appels, en pleine nuit, alors que le trafic du site restait faible à cette heure. En inspectant les journaux d’appels côté fournisseur, l’adresse IP d’origine ne correspondait à aucun serveur du domaine : un tiers avait extrait la clé du code source public et l’utilisait pour ses propres besoins, à l’insu du site viticole.

La faille dans le thème

L'essentiel à retenir : La clé apparaissait en clair dans un fichier JavaScript public ; Le fournisseur météo l'a désactivée après un pic d'usage anormal ; La correction passe par un point de terminaison proxy côté serveur

Le fichier en cause ressemblait à ceci, chargé par wp_enqueue_script() sans aucune protection :

function domaine_meteo_widget() {
  fetch('https://api.meteo-agri.example/v1/forecast?key=abcd1234EXPOSEE⪫=44.8&lon;=-0.5')
    .then(r => r.json())
    .then(data => afficherPrevisions(data));
}

Toute personne ouvrant les outils de développement du navigateur, ou même simplement le code source de la page, pouvait copier cette URL et l’utiliser depuis n’importe où. Aucune restriction par domaine référent n’avait été configurée côté fournisseur, ce qui a facilité l’exploitation.

Le correctif appliqué

La solution retenue déplace l’appel côté serveur, via un point de terminaison REST propre au site, qui interroge le service météo avec la clé stockée dans la configuration serveur et renvoie uniquement les données de prévision au navigateur :

add_action('rest_api_init', function () {
  register_rest_route('domaine/v1', '/meteo', array(
    'methods'  => 'GET',
    'callback' => 'domaine_meteo_proxy',
    'permission_callback' => '__return_true',
  ));
});

function domaine_meteo_proxy() {
  $cle = defined('METEO_AGRI_CLE') ? METEO_AGRI_CLE : '';
  $reponse = wp_remote_get(
    "https://api.meteo-agri.example/v1/forecast?key={$cle}⪫=44.8&lon;=-0.5"
  );
  if (is_wp_error($reponse)) {
    return new WP_REST_Response(array('erreur' => 'indisponible'), 502);
  }
  return json_decode(wp_remote_retrieve_body($reponse));
}

Le navigateur n’a plus jamais accès à la clé : il interroge /wp-json/domaine/v1/meteo, et c’est le serveur WordPress qui porte l’appel externe avec ses propres identifiants, protégés hors de portée du public.

Ce qui a été fait auprès du fournisseur

Le fournisseur météo a révoqué l’ancienne clé et une nouvelle a été générée. Sur cette famille de services, il est courant de pouvoir restreindre une clé à une liste de domaines référents autorisés : cette option, ignorée lors de la première intégration, a été activée en complément du proxy côté serveur, en défense en profondeur.

Un réflexe à généraliser

Toute intégration qui affiche une donnée provenant d’un service tiers mérite la même question : la clé transite-t-elle par le navigateur, ou reste-t-elle sur le serveur ? Dès qu’un appel fetch ou XMLHttpRequest contient un paramètre nommé key, token ou api_key directement dans son URL visible côté client, il s’agit d’un signal d’alerte à traiter avant la mise en production, pas après un pic d’usage suspect.

En résumé

Une clé d’API exposée dans un thème n’est jamais un problème abstrait : elle se traduit par une facture inattendue, un quota épuisé ou, pire, un accès détourné à des fonctionnalités payantes. Le réflexe du proxy côté serveur, couplé à la restriction par domaine référent côté fournisseur, referme durablement ce type de faille pour un coût de développement modeste.

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