wpDiscuz <= 7.6.42 - Unauthenticated Insecure Direct Object Reference
Description
The Comments – wpDiscuz plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 7.6.42 due to missing validation on a user controlled key. This makes it possible for unauthenticated attackers to perform unauthorized actions.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=7.6.42Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2025-68997 (wpDiscuz IDOR) ## 1. Vulnerability Summary The **Comments – wpDiscuz** plugin for WordPress is vulnerable to an **Insecure Direct Object Reference (IDOR)** in versions up to and including 7.6.42. The vulnerability exists in the handling of unauthentica…
Show full research plan
Exploitation Research Plan - CVE-2025-68997 (wpDiscuz IDOR)
1. Vulnerability Summary
The Comments – wpDiscuz plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) in versions up to and including 7.6.42. The vulnerability exists in the handling of unauthenticated AJAX actions related to comment subscriptions and follows (specifically the wpdUnsubscribe or wpdCancelFollow actions).
The plugin fails to properly validate that a user-provided "key" (intended to authorize an action on a specific resource) actually corresponds to the resource ID being manipulated. An unauthenticated attacker can provide their own valid key (or potentially an arbitrary one) alongside a victim's subscription ID to perform unauthorized actions, such as unsubscribing other users from comment threads.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
wpdUnsubscribe(inferred from common wpDiscuz subscription workflows) orwpdCancelFollow. - Method: POST
- Payload Parameters:
action:wpdUnsubscribesId: The numeric ID of the subscription to be canceled (Object Reference).sKey: A key used for authorization (User-Controlled Key).nonce: A valid WordPress nonce for the AJAX action.
- Authentication: Unauthenticated (
wp_ajax_nopriv_hook). - Preconditions: At least one active comment subscription must exist in the database for the victim.
3. Code Flow
- Entry Point: An unauthenticated user sends a POST request to
admin-ajax.phpwithaction=wpdUnsubscribe. - Hook Registration: The plugin registers the handler in
includes/class-wpdiscuz-ajax.php(orincludes/class.wpDiscuz.php) using:add_action('wp_ajax_nopriv_wpdUnsubscribe', array($this, 'wpdUnsubscribe')); - Handler Execution: The
wpdUnsubscribe()function retrievessIdandsKeyfrom the$_POSTarray. - The Sink: The code likely checks if
sKeyis present but fails to verify thatsKeyis the specific key associated with the record identified bysIdin the{$wpdb->prefix}wc_comments_subscriptiontable. - Unauthorized Action: The plugin proceeds to call a database method (e.g.,
$this->dbManager->unsubscribe($sId)) which deletes the subscription record regardless of whether the key matches that specific ID.
4. Nonce Acquisition Strategy
The wpDiscuz plugin enqueues a central JavaScript object containing configuration and nonces on any page where comments are active.
- Identify Script Loading: The script
wpdiscuz-ajax-jsis typically loaded on any post or page with comments enabled. - Setup Post: Create a post that allows comments.
wp post create --post_type=post --post_title="Vuln Test" --post_status=publish --comment_status=open - Navigate and Extract:
- Use
browser_navigateto visit the newly created post. - Use
browser_evalto extract the nonce from thewpdiscuzAjaxObjglobal variable. - JavaScript Variable:
window.wpdiscuzAjaxObj - Nonce Key:
nonce - Command:
browser_eval("window.wpdiscuzAjaxObj?.nonce")
- Use
- Note: If
wpdiscuzAjaxObjis not found, check forwpdiscuz_optionsor similar localized strings in the page source.
5. Exploitation Strategy
- Setup Victim Data: Create a subscription for a victim email address to generate a valid
sIdin the database. - Setup Attacker Data: Create a separate subscription for an attacker email address to obtain a "valid"
sKey(if the plugin requires any valid key) or simply use an arbitrary string if the check is completely missing. - Trigger IDOR:
- Construct a POST request to
admin-ajax.php. - Set
sIdto the Victim's ID (which is usually an incremental integer). - Set
sKeyto the Attacker's key or a random string. - Include the
nonceobtained in Step 4.
- Construct a POST request to
- HTTP Request Details:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=wpdUnsubscribe&sId=[VICTIM_SID]&sKey=[ATTACKER_SKEY]&nonce=[NONCE]
- URL:
6. Test Data Setup
- Enable Plugin: Ensure
wpdiscuzis active. - Generate Subscriptions:
The easiest way to populate the table{$wpdb->prefix}wc_comments_subscriptionfor testing is viawp eval:global $wpdb; $table = $wpdb->prefix . "wc_comments_subscription"; // Victim Subscription (ID will be 1) $wpdb->insert($table, ['post_id' => 1, 'email' => 'victim@example.com', 'subscription_type' => 'all', 'confirm_key' => 'victim_key', 'status' => 1]); // Attacker Subscription (ID will be 2) $wpdb->insert($table, ['post_id' => 1, 'email' => 'attacker@example.com', 'subscription_type' => 'all', 'confirm_key' => 'attacker_key', 'status' => 1]); - Confirm IDs: Verify the IDs using
wp db query "SELECT * FROM wp_wc_comments_subscription".
7. Expected Results
- Successful Request: The server returns a JSON response (e.g.,
{"success":true}) or a successful status indicator used by wpDiscuz. - Database Impact: The record in the
wp_wc_comments_subscriptiontable corresponding to thesIdof the victim is deleted or its status is changed, even though the attacker did not provide the victim's secret key.
8. Verification Steps
- Check Database: After the exploit request, run:
wp db query "SELECT count(*) FROM wp_wc_comments_subscription WHERE email='victim@example.com'" - Success Condition: The count should be
0(if deleted) or thestatusshould be changed, indicating the IDOR was successful.
9. Alternative Approaches
- Action Variation: If
wpdUnsubscribeis not the correct action name, investigatewpdCancelFolloworwpdUnfollowUserinincludes/class-wpdiscuz-ajax.php. - Key Discovery: If the plugin validates that the
sKeymust be a valid key from the database (but not necessarily the right one for that ID), the strategy of using the Attacker's own validsKeyto delete the Victim'ssIdis the primary fallback. - Brute Force sId: Since
sIdis likely an auto-incrementing integer, an attacker can iterate through IDs (e.g., 1-100) to mass-unsubscribe users.
Summary
The wpDiscuz plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) in versions up to and including 7.6.42. This allows unauthenticated attackers to perform unauthorized actions, such as unsubscribing other users from comment threads, due to a failure to validate that a provided authorization key matches the specific subscription record being accessed.
Exploit Outline
The vulnerability occurs within unauthenticated AJAX handlers responsible for subscription management. An attacker can initiate a request to modify a subscription by referencing its numeric ID. Because the application does not properly verify the relationship between the subscription ID and the authorization key provided in the request, the attacker can successfully perform actions on records they do not own by supplying their own key or a generic value.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.