veilletech.fr
25 août Feed du jour
#03 PHP Article

SAML WordPress : moins un vaut vrai, et on entre

En PHP, comparer strictement n'est pas un détail de style.

Deux vulnérabilités du plugin miniOrange SAML SSO pour WordPress permettent de forger une réponse SAML et d'obtenir un cookie d'administrateur. La seconde tient à une erreur PHP élémentaire : le retour -1 d'openssl_verify, évalué comme un booléen, est vrai.

3 min de lecturevidéo 1:24
Partager
Sommaire5 sections
  1. Ce qui se passe
  2. Deux failles, deux leçons
  3. Pourquoi ça compte
  4. Comment s'y prendre
  5. À retenir

Ce qui se passe

Le plugin miniOrange SAML 2.0 SSO pour WordPress — édition gratuite et six éditions payantes — accepte des réponses SAML forgées. Deux identifiants ont été attribués, CVE-2026-61979 et CVE-2026-15981, sur la base d'une analyse Patchstack relayée par DigitalOcean Security. Le résultat est le même dans les deux cas : un cookie d'authentification WordPress émis pour l'utilisateur de son choix, administrateur compris, sans mot de passe et sans compromettre le fournisseur d'identité.

Ce ne sont pas des scénarios de laboratoire. DigitalOcean rapporte une session d'administration détournée sur un site réel, et des balayages des points d'entrée SAML depuis plusieurs régions.

Deux failles, deux leçons

Confusion d'algorithme

L'attaquant lit la clé publique RSA du fournisseur d'identité — une information publique par construction, présente dans les métadonnées — puis annonce HMAC-SHA1 comme méthode de signature et signe son assertion en utilisant cette clé publique comme secret partagé.

Le plugin fait confiance à l'algorithme déclaré par la réponse qu'il est en train de vérifier. Il traite donc une clé publique comme un secret HMAC, recalcule la même empreinte que l'attaquant, et conclut que la signature est valide.

Le retour à trois valeurs

La seconde faille est celle que tout développeur PHP devrait garder en tête. openssl_verify() ne renvoie pas un booléen :

PHP
// 1  → signature valide
// 0  → signature invalide
// -1 → erreur de traitement
if ( openssl_verify( $data, $signature, $key ) ) {
    // -1 est truthy : la branche est prise sur une erreur OpenSSL
}

Le plugin évaluait ce retour comme une condition. Or -1 est vrai en PHP. Il suffit donc d'envoyer une signature qui provoque une erreur interne d'OpenSSL pour que la vérification soit considérée comme réussie.

Pourquoi ça compte

Un point d'entrée SAML est exposé à internet par nature : c'est son rôle. Aucune interaction de la victime n'est requise, aucun facteur d'authentification n'est sollicité, et le fournisseur d'identité ne voit rien passer. Côté journaux, la signature de l'attaque est justement cette asymétrie : une connexion SAML réussie côté WordPress sans authentification correspondante côté fournisseur.

Avec un cookie d'administrateur, l'attaquant modifie articles, réglages, comptes, extensions et thèmes — et sur une installation qui autorise l'édition de fichiers, cela mène à l'exécution de code sur le serveur.

Comment s'y prendre

  1. Mettre à jour l'édition exacte. Les sept éditions partagent le même identifiant de plugin, mais chacune a sa propre numérotation. Un contrôle du type « au moins 5.4.5 » laisse donc passer toutes les éditions payantes.
Code
édition                                    version corrigée
gratuite                                   5.4.5
Premium (mono-site)                        13.0.4
Standard                                   17.0.6
Premium / Enterprise / All-Inclusive (multisite)   20.2.8
Enterprise / All-Inclusive (mono-site)     26.0.3
VIP (mono-site)                            32.0.8
VIP (multisite)                            35.0.7
  1. Vérifier manuellement. Les éditions payantes ne remontent pas toujours de notification de mise à jour dans le tableau de bord.
  2. En attendant : refuser HMAC-SHA1 sur le point d'entrée, comparer strictement openssl_verify( ... ) === 1, poser une règle de pare-feu applicatif, et restreindre /wp-admin à un réseau de confiance — c'est ce qui a limité les dégâts dans le cas observé.

À retenir

Deux principes en sortent, valables bien au-delà de WordPress : ne jamais laisser le message décider de l'algorithme qui le valide, et ne jamais tester en booléen une fonction qui distingue l'échec de l'erreur.

Source : DEV Community