
PoC de CVE-2025-22783
Plugin WordPress
Nom du composant SEO Plugin by Squirrly SEO
Version vulnérable <= 12.4.01
Slug du composant squirrly-seo
Lien du composant https://wordpress.org/plugins/squirrly-seo/
Classe de vulnérabilité A3: Injection
Type de vulnérabilité Injection SQL
Contributor +
Le plugin SEO Squirrly SEO vous permet d'améliorer le SEO de votre site web grâce à une fonctionnalité de liens internes qui vous permet de sélectionner des pages sources et cibles en fonction de mots-clés spécifiques. Vous pouvez gérer les mots-clés, les pages sources, les pages cibles et le statut de chaque lien via la page de gestion des liens internes (/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks).
Dans les versions 12.4.01 et inférieures du plugin Squirrly SEO, vous pouvez rechercher des liens internes créés sur la page de gestion des liens internes. Une vulnérabilité d'injection SQL se produit lorsque les termes de recherche saisis par les utilisateurs (Contributor+) sont transmis directement aux requêtes de la base de données sans validation.
Bien que les résultats de recherche ne soient pas directement affichés sur la page de gestion des liens internes, les informations de la base de données peuvent être extraites à l'aide de techniques d'injection SQL basées sur le temps, comme la fonction SLEEP.
Connectez-vous au site cible avec un compte disposant de privilèges de niveau Contributor ou supérieur, sur lequel le plugin Squirrly SEO version 12.4.01 ou inférieure est installé.
Ensuite, lorsque vous accédez à l'URL ci-dessous, comme la condition de l'instruction IF '1=1' dans la charge utile d'injection SQL est toujours vraie, la fonction SLEEP(5) s'exécute et la page se charge après 5 secondes.
http://localhost:8080/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks&stype&squery='+AND+1%3D2)+UNION+SELECT+(IF(1=1,SLEEP(5),1)),2,3,4,5,6,7%23
En revanche, si vous modifiez la condition de l'instruction IF à '1=2', la page se chargera immédiatement car la valeur du résultat est fausse.
http://localhost:8080/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks&stype&squery='+AND+1%3D2)+UNION+SELECT+(IF(1=2,SLEEP(5),1)),2,3,4,5,6,7%23
Sur la page de gestion des liens internes (/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks) du plugin Squirrly SEO, lors de la recherche de liens internes, il interroge la base de données en appelant la fonction getSqInnerlinks dans le fichier /wp-content/plugins/squirrly-seo/models/Qss.php.

À ce stade, nous pouvons voir que la variable $query_where est directement insérée dans la requête SQL. Examinons comment la valeur de la variable $query_where est construite:
$search contient le terme de recherche saisi lors de la recherche de liens internes, et la fonction sanitize_text_field est utilisée pour traiter les données saisies par l'utilisateur.$search est utilisée comme partie de la clause conditionnelle et stockée dans la variable $query_where.$query_where, et des filtres sont appliqués via la fonction apply_filters.Par conséquent, bien que le terme de recherche saisi par les utilisateurs lors de la recherche de liens internes soit traité par la fonction sanitize_text_field, cette fonction ne peut pas empêcher les attaques par injection SQL. Les caractères spéciaux utilisés dans les requêtes SQL (guillemets simples ('), commentaires (#), etc.) ne sont pas filtrés, et lorsque la variable $search contenant la charge utile d'injection SQL est transmise à la requête de la base de données sans échappement approprié, une vulnérabilité d'injection SQL se produit.
⚠️ Le code PoC implémenté se connecte avec un compte administrateur pour créer un compte avec les privilèges minimaux (Contributor+) requis pour la reproduction de la vulnérabilité, puis déclenche la vulnérabilité à l'aide de ce compte.

Module requisrequests
python poc.py
