vendredi 25 septembre 2026

À propos

Contact

Sécurité

SSRF dans WordPress : wp_safe_remote_get et les URL fournies par l’utilisateur

Un champ « importer depuis une URL » mal conçu peut servir à sonder le réseau interne d'un hébergeur. Le rôle méconnu de wp_safe_remote_get.

Par Clément Hadrot • 22 janvier 2021 • 4 min de lecture • Aucun commentaire
SSRF dans WordPress : wp_safe_remote_get et les URL fournies par l'utilisateur

Une extension d’import de contenu propose à l’utilisateur de coller une URL pour en récupérer l’image mise en avant. Fonctionnalité pratique, mais qui cache un risque rarement anticipé : si le code va chercher cette URL sans aucune restriction, rien n’empêche un attaquant de fournir une adresse pointant non pas vers une image sur internet, mais vers un service interne du serveur lui-même, invisible depuis l’extérieur en temps normal.

Cette classe de vulnérabilité porte un nom : la falsification de requête côté serveur, ou SSRF (Server-Side Request Forgery). Le serveur devient, malgré lui, le complice d’une requête que l’attaquant ne pourrait pas envoyer directement. WordPress atténue une partie de ce risque nativement, mais pas dans tous les cas de figure.

Comment une simple récupération d’URL devient un risque

Sur de nombreux hébergements, des services internes écoutent sur des adresses non routables depuis internet, mais accessibles depuis le serveur lui-même : une API de métadonnées cloud, un tableau de bord d’administration technique, une base de données exposée sur le réseau local sans authentification stricte parce qu’elle « n’est de toute façon pas accessible depuis l’extérieur ». Une fonction qui récupère une URL fournie sans restriction, comme un appel brut à curl ou à file_get_contents() sur une entrée utilisateur, peut être détournée pour atteindre ces services :

// Code vulnérable : aucune restriction sur la destination
$contenu = file_get_contents( $_POST['url_image'] );

Un attaquant fournirait alors une adresse comme http://169.254.169.254/ ou http://127.0.0.1:9200/ plutôt qu’une véritable URL d’image, dans l’espoir d’obtenir une réponse révélant des informations internes au serveur.

Ce que fait wp_safe_remote_get par défaut

WordPress fournit une famille de fonctions pour les requêtes HTTP sortantes, dont wp_remote_get() et sa variante wp_safe_remote_get(). Cette dernière applique par défaut le filtre http_request_host_is_external, qui refuse les requêtes vers les plages d’adresses IP privées et de bouclage (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) sauf configuration explicite contraire :

$reponse = wp_safe_remote_get( $_POST['url_image'] );

if ( is_wp_error( $reponse ) ) {
    wp_die( esc_html__( 'URL non autorisée ou inaccessible.', 'mon-extension' ) );
}

$corps = wp_remote_retrieve_body( $reponse );

Utiliser wp_safe_remote_get() plutôt que wp_remote_get() dès qu’une URL provient d’une saisie utilisateur constitue le premier réflexe à adopter : la différence entre les deux fonctions tient précisément à cette vérification de sécurité.

L'essentiel à retenir : Une fonction d'import d'URL peut atteindre des adresses internes au serveur ; wp_safe_remote_get bloque par défaut les plages d'adresses privées ; Le filtrage reste incomplet face aux redirections HTTP en chaîne

Pourquoi ce filtrage reste incomplet

Le filtre natif de WordPress vérifie l’hôte au moment de la requête initiale, mais ne rejoue pas systématiquement la même vérification à chaque redirection HTTP rencontrée en chemin selon la configuration et la version. Un attaquant peut ainsi fournir une URL publique parfaitement légitime, qui répond elle-même par une redirection HTTP vers une adresse interne. C’est une limite documentée de ce type de protection, pas spécifique à WordPress : elle touche toute bibliothèque HTTP qui suit les redirections automatiquement.

  • Limiter le nombre de redirections suivies via l’argument redirection passé à la fonction, en le réduisant au strict nécessaire.
  • Ne jamais afficher directement le contenu brut de la réponse à l’utilisateur sans traitement, ce qui limiterait l’intérêt d’une tentative de sondage interne.
  • Sur les besoins sensibles, valider explicitement le domaine attendu avant même d’appeler la fonction de requête, en plus du filtrage natif.

Un réflexe de conception à adopter

Toute fonctionnalité qui va chercher une URL fournie par un utilisateur doit être pensée comme si cet utilisateur pouvait tenter d’atteindre votre propre serveur, pas seulement le web public.

Ce principe s’applique à l’import d’images depuis une URL, à la validation d’un webhook entrant qui vérifie une URL de rappel, ou à toute extension qui propose de « tester la connectivité » vers une adresse fournie. Dans chacun de ces cas, la question à se poser est la même : que se passe-t-il si la valeur fournie ne pointe pas vers ce qui était attendu ?

En résumé

Le risque SSRF touche toute fonctionnalité WordPress qui effectue une requête HTTP vers une adresse choisie par l’utilisateur. Préférer systématiquement wp_safe_remote_get() à wp_remote_get() dans ce contexte apporte une protection native appréciable, à compléter par une vigilance sur les redirections et par une validation de domaine explicite pour les usages les plus sensibles.

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