
Prueba de concepto de CVE-2025-22783
Plugin de WordPress
Component name Plugin SEO de Squirrly SEO
Vulnerable version <= 12.4.01
Component slug squirrly-seo
Component link https://wordpress.org/plugins/squirrly-seo/
Vulnerability class A3: Inyección
Vulnerability type Inyección SQL
Contributor +
El Plugin SEO de Squirrly SEO te permite mejorar el SEO de tu sitio web mediante una función de enlaces internos que te permite seleccionar páginas de origen y destino basadas en palabras clave específicas. Puedes gestionar las palabras clave, páginas de origen, páginas de destino y el estado de cada enlace a través de la página de gestión de enlaces internos (/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks).
En las versiones 12.4.01 e inferiores del plugin Squirrly SEO, puedes buscar enlaces internos creados en la página de gestión de enlaces internos. Se produce una vulnerabilidad de Inyección SQL cuando los términos de búsqueda introducidos por los usuarios (Contributor+) se pasan directamente a las consultas de la base de datos sin validación.
Si bien los resultados de búsqueda no se muestran directamente en la página de gestión de enlaces internos, se puede extraer información de la base de datos utilizando técnicas de Inyección SQL basada en tiempo, como la función SLEEP.
Inicia sesión en el sitio objetivo con una cuenta que tenga privilegios de Contributor o superiores donde esté instalado el plugin Squirrly SEO versión 12.4.01 o inferior.
Luego, cuando accedas a la URL siguiente, dado que la condición de la declaración IF '1=1' en el payload de Inyección SQL siempre es verdadera, la función SLEEP(5) se ejecutará y la página se cargará después de 5 segundos.
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
Por otro lado, si cambias la condición de la declaración IF a '1=2', la página se cargará inmediatamente porque el resultado es falso.
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
En la página de gestión de enlaces internos (/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks) del plugin Squirrly SEO, al buscar enlaces internos, consulta la base de datos llamando a la función getSqInnerlinks en el archivo /wp-content/plugins/squirrly-seo/models/Qss.php.

En este punto, podemos ver que la variable $query_where se inserta directamente en la consulta SQL. Examinemos cómo se construye el valor de la variable $query_where:
$search contiene el término de búsqueda ingresado durante la búsqueda de enlaces internos, y la función sanitize_text_field se utiliza para procesar los datos de entrada del usuario.$search se utiliza como parte de la cláusula condicional y se almacena en la variable $query_where.$query_where, y se aplican filtros a través de la función apply_filters.Por lo tanto, si bien el término de búsqueda ingresado por los usuarios durante la búsqueda de enlaces internos es procesado por la función sanitize_text_field, esta función no puede prevenir ataques de Inyección SQL. Los caracteres especiales utilizados en consultas SQL (comillas simples ('), comentarios (#), etc.) no se filtran, y cuando la variable $search que contiene el payload de Inyección SQL se pasa a la consulta de la base de datos sin el escape adecuado, se produce una vulnerabilidad de Inyección SQL.
⚠️ El código PoC implementado inicia sesión con una cuenta de administrador para crear una cuenta con privilegios mínimos (Contributor+) necesarios para la reproducción de la vulnerabilidad, y luego activa la vulnerabilidad utilizando esa cuenta.

A continuación, ingresa el siguiente comando para ejecutar el código PoC.
Required modulerequests
python poc.py
