Alerta de seguridad
Nivel de peligrosidad: Alto
CVE-2022–21661
Descripción
El núcleo de wordpress proporciona funciones para que los complementos (plugins) llamen y usen las funciones nativas de wordpress, como: formato de datos, consultas a la BD, etc. Entre las clases que proporciona wordpress, se ha encontrado que la clase utlizada para realizar consultas a la base de datos (WP_Query) es vulnerable a inyección SQL.
Análisis de errores
En la versión 5.8.3, wordpress ha corregido este error, en la comparación de cambios se puede ver que en la función `clean_query` se ha agregado una verificación `$query['field']` antes de procesar la variable `$query['terms']`.
![Comparación de código fuente con la actualización](/sites/default/files/inline-images/01_graf_1.png)
La función `clean_query` se llama desde `get_sql_for_clause`. Al verificar el código de la función, se puede ver que el rol de esta función es crear cláusulas para la condición en una consulta SQL, específicamente su rol será procesar los datos recibidos, combinar esos datos en una condición en la consulta SQL y devolverla a la función principal. Por tanto, se pueden controlar los datos de retorno de esta función, lo que significa que podemos controlar la consulta SQL y realizar la inyección SQL.
![código fuente de la función get_sql_for_clause](/sites/default/files/inline-images/02_graf_2.png)
Volviendo a la función `clean_query`, cuando no se ha realizado este cambio, por defecto los valores en `$query['terms']` solo se borrarán y luego se llamará a `$this->transform_query( $query, 'term_taxonomy_id');` .
Para evitar caer en `if` (fila 561 en el gráfico), `$query['taxonomy']` debe estar vacío o se debe ingresar un valor para que al comparar en `is_taxonomy_hierarchical` devuelva `false`.
![Código fuente WordPress](/sites/default/files/inline-images/03_graf_3.png)
La función `transform_query` verificará si `$query['field'] == $resulting_field`, en caso afirmativo, regresará y no hará más procesamiento, por lo que si la variable `$query['field']` es igual a `term_taxonomy_id`, podemos salir de la función sin cambiar el valor de la variable `$query['terms']`.
![Código fuente WordPress](/sites/default/files/inline-images/04_graf_4.png)
Después de salir de la función, el flujo de código de regreso a la posición llamará a `clean_query` una función `get_sql_for_clause`. El valor de la variable `$query['terms']` se usará directamente como condición de consulta SQL y conducirá a la inyección SQL.
![Código fuente WordPress](/sites/default/files/inline-images/05_graf_5.png)
Entonces, en resumen, para que ocurra la inyección SQL, se deben cumplir dos condiciones:
- Que `$query['field']` sea igual a `term_taxonomy_id`
- Que `$query['taxonomy']` sea vacío o `is_taxonomy_hierarchical($query['taxonomy']) === false`
El flujo da como resultado el siguiente error:
![Error que evidencia la vulnerabilidad a SQLi](/sites/default/files/inline-images/06_graf_6.png)
Explotación
Aunque este error es del núcleo de wordpress, la forma en que el núcleo de wordpress lo usa no desencadena el error, por lo que el error se presenta en complementos (plugins) que realicen llamadas a la clase `WP_Query`, es decir cuando se realicen consultas a la base de datos. La forma de identificar el error es cuando el complemento usa `WP_Query($data)` y el parámetro `$data` se puede controlar.
Por ejemplo, `new WP_Query(json_decode($_POST['query_vars']))`, la carga útil (Payload) sería de la siguiente forma:
`query_vars = {"tax_query": {"0": {"field": "term_taxonomy_id", "terms": ["<inject>"]}}}
o
query_vars = {"tax_query": {"0": {"taxonomy": "nav_menu", "field": true, "terms": ["<inject>"]}}}`
La manera más sencilla de identificar la vulnerabilidad es cuando el modo de depuración (modo debug) está habilitado.
![Captura de paquete que evidencia la existencia de la vulnerabilidad](/sites/default/files/inline-images/07_graf_7.png)
Recursos afectados
WP_Query, core de wordpress anteriores a 5.8.3
Solución/Mitigación
Actualizar WordPress a la versión 5.8.3.
Recomendaciones
Debido a que muchos complementos realizan consultas a la base de datos, se recomienda actualizar WordPress de manera urgente a la versión 5.8.3, también es recomendable mantener activa las actualizaciones automáticas.
Referencias
SQL Injection in Wordpress core (CVE-2022–21661)
WordPress Core WP_Query SQL Injection Information Disclosure Vulnerability