# Redirections ouvertes : wp_safe_redirect plutôt que wp_redirect

> Une redirection après connexion qui accepte n'importe quelle URL devient un outil de phishing clé en main. Le correctif tient en une fonction.

- Auteur : Clément Hadrot
- Publié le : 2021-01-07
- Mis à jour le : 2021-01-07
- Catégorie : Sécurité
- URL : https://wpmoderne.dev.wordpress-developpement.fr/securite/redirections-ouvertes-wp-safe-redirect/

## L’essentiel

- Une redirection ouverte détourne la confiance dans le nom de domaine réel
- wp_safe_redirect restreint la destination à une liste d'hôtes autorisés
- allowed_redirect_hosts permet d'ajouter des domaines de confiance légitimes

Un client reçoit un jour un signalement inquiétant : des liens portant le nom de domaine de son site, partagés dans des campagnes de phishing, redirigent en réalité vers une fausse page de connexion bancaire. En y regardant de plus près, le lien exploite un paramètre de redirection après connexion, présent dans une extension installée sur le site, qui accepte n'importe quelle URL de destination sans vérification.

Ce type de vulnérabilité s'appelle une redirection ouverte. Elle ne compromet pas directement le site lui-même, mais détourne la confiance que les internautes accordent à son nom de domaine pour les rediriger, sans qu'ils s'en aperçoivent, vers un site malveillant. WordPress fournit une fonction conçue précisément pour éviter ce piège.

## Comment naît une redirection ouverte

Le scénario le plus courant apparaît dans du code d'authentification personnalisé, où une URL de retour est passée en paramètre pour renvoyer l'utilisateur là où il se trouvait avant de se connecter :

```
// Code vulnérable
$destination = $_GET['redirect_to'] ?? home_url();
wp_redirect( $destination );
exit;
```

Rien dans ce code ne vérifie que `redirect_to` pointe bien vers une page du site. Un attaquant construit alors un lien du type `https://exemple.fr/connexion/?redirect_to=https://faux-site-bancaire.exemple/`, qui semble provenir du domaine de confiance dans la barre d'adresse jusqu'au moment de la redirection, puis bascule silencieusement vers la destination malveillante une fois l'utilisateur authentifié.

## La fonction native pensée pour ce cas

WordPress fournit `wp_safe_redirect()` précisément pour ce besoin : elle se comporte comme `wp_redirect()`, mais vérifie au préalable que l'hôte de destination fait partie d'une liste d'hôtes autorisés. Si ce n'est pas le cas, elle redirige automatiquement vers la racine du site plutôt que vers la destination fournie :

```
$destination = $_GET['redirect_to'] ?? home_url();
wp_safe_redirect( $destination );
exit;
```

Par défaut, la liste des hôtes autorisés se limite au domaine du site lui-même, tel que retourné par `home_url()`, ce qui couvre déjà la très large majorité des usages légitimes de redirection après connexion ou après soumission de formulaire.

> L'essentiel à retenir : Une redirection ouverte détourne la confiance dans le nom de domaine réel ; wp_safe_redirect restreint la destination à une liste d'hôtes autorisés ; allowed_redirect_hosts permet d'ajouter des domaines de confiance légitimes

## Étendre la liste des hôtes de confiance

Certains scénarios légitimes nécessitent de rediriger vers un domaine tiers connu, par exemple une plateforme de paiement partenaire ou un sous-domaine séparé. Le filtre `allowed_redirect_hosts` permet d'étendre la liste sans désactiver la protection :

```
add_filter( 'allowed_redirect_hosts', function ( $hotes ) {
    $hotes[] = 'paiement.partenaire-exemple.fr';
    return $hotes;
} );
```

Chaque ajout à cette liste doit rester justifié : plus elle grandit sans discernement, plus elle réintroduit une partie du risque initial pour les domaines ajoutés.

## Repérer les redirections ouvertes existantes

Dans une base de code existante, une recherche simple révèle rapidement les appels à surveiller :

```
grep -rn "wp_redirect(" wp-content/plugins/ wp-content/themes/
```

Chaque occurrence mérite un examen individuel : toutes les redirections ne présentent pas un risque, seules celles dont la destination dépend d'une donnée fournie par l'utilisateur (paramètre d'URL, champ de formulaire, en-tête HTTP) sont concernées.

## Ce qui ne suffit pas comme vérification

- Vérifier que l'URL commence par `http` ne filtre rien : une URL malveillante commence aussi par `http`.
- Vérifier qu'elle commence par le nom de domaine du site en tant que simple chaîne de caractères peut être contourné par des variantes comme `https://exemple.fr.faux-domaine.tld/`.
- Seule une vérification structurée de l'hôte, comme celle effectuée en interne par `wp_safe_redirect()` via `wp_validate_redirect()`, offre une garantie fiable.

> Une redirection qui fait confiance à un paramètre d'URL fourni par le visiteur transforme la confiance en votre nom de domaine en arme contre vos propres utilisateurs.

## En résumé

Remplacer `wp_redirect()` par `wp_safe_redirect()` dès qu'une destination dépend d'une donnée utilisateur ferme une vulnérabilité discrète mais aux conséquences réelles pour la réputation d'un site. Le filtre `allowed_redirect_hosts` permet d'ouvrir la porte à des partenaires de confiance sans revenir à une redirection totalement ouverte.
