CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-88974

CVE-2026-88974: Incorrect Authorization in WPGraphQL updatePost Mutation

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 23, 2026·7 min read·4 visits

Executive Summary (TL;DR)

An authorization vulnerability in WPGraphQL prior to 2.22.2 allows authenticated WordPress Contributors to bypass workflow restrictions and publish drafts or modify published posts without editorial oversight.

CVE-2026-88974 is an incorrect authorization vulnerability in the WPGraphQL plugin for WordPress. Due to a failure to perform object-level capability checks or validate status-transition requirements in the updatePost mutation handler, authenticated Contributor-level users can publish their own draft posts without editorial approval or modify their previously published posts.

Vulnerability Overview

CVE-2026-88974 represents an incorrect authorization vulnerability within the WPGraphQL plugin for WordPress. The flaw exists in the legacy updatePost mutation handler located in src/Mutation/PostObjectUpdate.php. The vulnerability affects all versions prior to 2.22.2, with vulnerability characteristics introduced starting in version 2.19.0. It exposes an attack surface to authenticated users holding low-privileged roles.

Under default WordPress access control configurations, a user with the Contributor role is permitted to write and edit draft posts but lacks permissions to publish them. This policy requires the publish_posts capability to ensure editorial oversight. Furthermore, Contributors are prohibited from modifying their own posts after publication unless they possess the edit_published_posts capability. WPGraphQL did not properly respect these fine-grained authorization boundaries within its GraphQL mutation API.

Instead of verifying dynamic, object-level capabilities, the plugin only checked high-level collection capabilities and post ownership. This oversight allows authenticated Contributors to execute mutations that publish draft posts or edit previously published content directly. This privilege escalation vector bypasses standard editorial workflows, leading to unauthorized modifications of published web content.

Root Cause Analysis

The root cause of CVE-2026-88974 is the failure of the WPGraphQL legacy mutation handler to evaluate WordPress object-level meta-capabilities. WordPress differentiates generic capabilities like edit_posts from dynamic meta-capabilities like edit_post. A meta-capability is evaluated against a specific post object dynamically to determine if the current user possesses authorization based on ownership and status.

When current_user_can('edit_post', $post_id) is invoked, WordPress maps the request to specialized primitive capabilities. If the target post status is a draft, it maps to edit_posts. If the target post status is published, it maps to edit_published_posts. Because normal Contributors do not possess edit_published_posts, any attempts to edit published content are rejected by the core capability framework.

WPGraphQL bypassed this mapping process in PostObjectUpdate.php. The handler verified only that the post author matched the executing user and that the user possessed the general edit_posts capability. By not invoking current_user_can on the specific object instance using edit_post, the code failed to detect that the user lacked permissions for published post modifications. Additionally, the code did not check the publish_posts capability during status transitions to public states.

Code-Level Analysis

The patch implemented in WPGraphQL version 2.22.2 introduces the missing validation checks in plugins/wp-graphql/src/Mutation/PostObjectUpdate.php. The code modification ensures that both object-level permissions and post-status transitions are checked against WordPress core security boundaries. This brings GraphQL mutation authorization parity with the native WordPress REST API.

The first critical fix implements validation of the dynamic meta-capability for the specific post object:

// Enforce the object-level edit capability for this specific post. WordPress maps
// the edit_post meta capability to edit_published_posts once a post is
// published, so a user who can create and edit drafts (e.g. a Contributor) cannot
// edit a post after it has been published. This mirrors the WordPress REST API,
// which returns rest_cannot_edit for the same request.
if ( ! isset( $post_type_object->cap->edit_post ) || ! current_user_can( $post_type_object->cap->edit_post, $post_id ) ) {
	// translators: the placeholder is the singular name of the post type being mutated
	throw new UserError( esc_html( sprintf( __( 'Sorry, you are not allowed to update this %1$s', 'wp-graphql' ), $post_type_object->graphql_single_name ) ) );
}

The second critical check stops unauthorized users from executing status updates that would make a draft publicly visible. If the incoming payload attempts a status transition that requires publication capability, the system explicitly verifies the user's publish_posts permission:

// If the update requests a status that requires publishing capability (anything
// other than draft or pending) and the current user cannot publish, reject the
// request rather than silently changing the post's visibility. This mirrors the
// WordPress REST API, which returns rest_cannot_publish for the same request.
if (
	isset( $post_args['post_status'] ) &&
	! in_array( $post_args['post_status'], [ 'draft', 'pending' ], true ) &&
	( ! isset( $post_type_object->cap->publish_posts ) || ! current_user_can( $post_type_object->cap->publish_posts ) )
) {
	// translators: the placeholder is the singular name of the post type being mutated
	throw new UserError( esc_html( sprintf( __( 'Sorry, you are not allowed to publish this %1$s', 'wp-graphql' ), $post_type_object->graphql_single_name ) ) );
}

These additions systematically close both bypass paths. Any requests attempting to modify a published post or publish a draft without appropriate credentials will fail during the pre-mutation validation phase, raising an explicit UserError exception.

Attack Methodology & Exploitation Scenario

An attacker with valid Contributor-level credentials can exploit this vulnerability via network access to the target /graphql endpoint. The attack does not require user interaction from other roles. Exploitation relies on craft mutations sent to the GraphQL parser.

To publish an unauthorized post, the attacker first registers or retrieves a post ID representing their draft. They then compile a GraphQL mutation that Targets the updatePost schema. By specifying the target Relay Global ID and defining the state transition within the variables, the restriction is bypassed.

mutation BypassPublishPost($input: UpdatePostInput!) {
  updatePost(input: $input) {
    post {
      databaseId
      status
      title
    }
  }
}

The following payload is supplied to trigger the state modification:

{
  "input": {
    "id": "cG9zdDoxMjM=",
    "status": "PUBLISH"
  }
}

When executed against a vulnerable instance of WPGraphQL, the backend modifies the database post state without conducting the appropriate publication check. The post is instantly available on the public site layout. The same mechanism can target existing, approved posts by modifying fields such as title or body text within the input variables.

Impact & Risk Assessment

The security impact of CVE-2026-88974 represents an application-level privilege escalation vector. While it does not facilitate Remote Code Execution (RCE) or sensitive database information exposure directly, it undermines the trust and integrity of the content publication pipeline.

On media websites or corporate sites where Contributor permissions are granted to external writers, this vulnerability permits the unauthorized injection of web content. Attackers can deface high-traffic pages, distribute malicious external links, or publish unapproved, misleading announcements. This compromises search engine optimization and can expose visitors to drive-by malware campaigns.

The vulnerability is scored with a CVSS v3.1 base score of 5.4. The vector string is CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L. This reflects network-level accessibility with low complexity and low privileges, resulting in a low impact on availability and confidentiality, but a low-to-medium impact on system integrity.

Remediation & Mitigation Guidance

The primary remediation strategy is the immediate upgrade of WPGraphQL to version 2.22.2 or higher. The patch enforces strict capability checks, neutralizing the logical bypass paths. Administrators can verify the active plugin version within the WordPress administration panel or via the Command Line Interface.

If immediate updates are unfeasible, temporary mitigation steps must be enacted. Administrators should temporarily suspend or downgrade accounts possessing the Contributor role to Subscriber status. Subscribers do not have baseline access to compile or submit mutations targeting the post collection, which mitigates the vulnerability.

Web Application Firewalls (WAFs) should be configured with custom rules designed to filter the GraphQL endpoint. Payload inspection rules can look for the combination of updatePost and status variables indicating PUBLISH within non-editorial user sessions. Security teams must monitor mutation access logs to identify attempts targeting the updatePost schema.

Fix Analysis (1)

Technical Appendix

CVSS Score
5.4/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L

Affected Systems

WordPress installations with WPGraphQL plugin prior to 2.22.2

Affected Versions Detail

Product
Affected Versions
Fixed Version
wp-graphql
wp-graphql
>= 2.19.0, < 2.22.22.22.2
AttributeDetail
CWE IDCWE-863 (Incorrect Authorization)
Attack VectorNetwork
CVSS v3.1 Score5.4
Exploit StatusPoC via test suite
ImpactPrivilege Escalation / Unauthorized Publication
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-863
Incorrect Authorization

The software performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly prove that the actor is authorized to perform that action or access that resource.

Known Exploits & Detection

GitHub (WPGraphQL Test Suite)The pull request contains high-fidelity regression unit tests verifying that Contributors can no longer publish drafts or modify published posts.

Vulnerability Timeline

Vulnerability patch committed to repository
2026-09-04
GitHub Security Advisory published
2026-09-23
WPGraphQL version 2.22.2 released
2026-09-23
CVE-2026-88974 assigned and published
2026-09-23

References & Sources

  • [1]GitHub Security Advisory GHSA-5mmc-8pc9-wggg
  • [2]WPGraphQL Pull Request 4270
  • [3]Vulnerability Fix Commit
  • [4]WPGraphQL 2.22.2 Release

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•26 minutes ago•CVE-2026-85724
9.6

CVE-2026-85724: Pattern-ACL Wildcard Injection & Cross-Tenant Authorization Bypass in Moquette MQTT Broker

CVE-2026-85724 is a critical vulnerability in the Moquette MQTT broker (versions prior to 0.18.1) where unvalidated substitution of client identifiers and usernames into pattern-based Access Control Lists (ACLs) permits remote authenticated attackers to bypass multi-tenant boundaries and trigger a Denial of Service.

Amit Schendel
Amit Schendel
0 views•7 min read
•about 2 hours ago•CVE-2026-73858
5.3

CVE-2026-73858: Server-Side Twig Template Injection in Solspace Freeform for Craft CMS

A technical analysis of CVE-2026-73858 / GHSA-gxrg-x694-283w, a server-side template injection vulnerability in the Solspace Freeform plugin for Craft CMS. The vulnerability permits unauthenticated users to trigger dynamic Twig evaluation of input fields during form validation re-rendering, causing local directory path disclosure and PHP runtime information exposure.

Alon Barad
Alon Barad
5 views•6 min read
•about 3 hours ago•CVE-2026-54892
8.7

CVE-2026-54892: Algorithmic Complexity Denial of Service in Plug Query Decoder

An algorithmic complexity vulnerability (CWE-407) in the query decoder of the Elixir Plug library (CVE-2026-54892) allows unauthenticated remote attackers to trigger scheduler starvation and denial of service by transmitting deeply nested brackets in query parameters or URL-encoded post bodies.

Alon Barad
Alon Barad
7 views•6 min read
•about 4 hours ago•CVE-2026-83801
5.4

CVE-2026-83801: Stored Cross-Site Scripting via Form Help Text in Nautobot

CVE-2026-83801 is a stored Cross-Site Scripting (XSS) vulnerability in Nautobot. The vulnerability arises because the application interpolates user-controlled database properties—specifically Relationship descriptions and Module Family names—directly into the help_text parameter of Django form fields. These fields are rendered using Django's |safe filter, bypassing HTML escaping and enabling persistent injection. When an administrative user accesses the affected forms, the payload executes contextually in their browser. This allows attackers to hijack active sessions and perform unauthorized operations. Nautobot versions prior to v2.4.37 and v3.1.8 are affected by this vulnerability. The issue has been patched by implementing contextual HTML escaping and strict markdown sanitization.

Alon Barad
Alon Barad
5 views•5 min read
•about 5 hours ago•CVE-2026-83805
6.4

CVE-2026-83805: Authorization Bypass and Privilege Escalation in Nautobot Approval Workflows

An authorization bypass vulnerability exists in Nautobot's REST API endpoints handling approval workflows. Due to an architectural inconsistency, a standalone, generic REST API endpoint for creating approval responses was exposed without propagating the required business-logic validations. This allows low-privileged authenticated users to submit forged, self-approved votes, bypassing approval thresholds and triggering unauthorized server-side automated jobs.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 6 hours ago•CVE-2026-85709
5.3

CVE-2026-85709: Sensitive Information Exposure in LightRAG API Server

CVE-2026-85709 is a sensitive information exposure vulnerability in HKUDS LightRAG prior to version 1.5.5. The vulnerability allows remote, unauthenticated clients to trigger server-side errors and receive raw Python exception details, including local filesystem paths, database connection strings, credentials, and internal system configurations.

Amit Schendel
Amit Schendel
5 views•6 min read