CVE-2025-66080

Cookie Notice for GDPR, CCPA & ePrivacy Consent <= 4.0.3 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.0.4
Patched in
7d
Time to patch

Description

The Cookie Notice for GDPR, CCPA & ePrivacy Consent plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the wpl_data_req_process_delete() function in versions up to, and including, 4.0.3. This makes it possible for unauthenticated attackers to delete data.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.0.3
PublishedDecember 30, 2025
Last updatedJanuary 5, 2026
Affected plugingdpr-cookie-consent

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2025-66080 - Missing Authorization in Cookie Notice for GDPR, CCPA & ePrivacy Consent ## 1. Vulnerability Summary The **Cookie Notice for GDPR, CCPA & ePrivacy Consent** plugin (versions <= 4.0.3) is vulnerable to unauthorized data modification due to a missing capability check…

Show full research plan

Research Plan: CVE-2025-66080 - Missing Authorization in Cookie Notice for GDPR, CCPA & ePrivacy Consent

1. Vulnerability Summary

The Cookie Notice for GDPR, CCPA & ePrivacy Consent plugin (versions <= 4.0.3) is vulnerable to unauthorized data modification due to a missing capability check in the wpl_data_req_process_delete() function. This function is responsible for processing the deletion of data requests (likely GDPR erasure requests). Because it fails to verify that the requester has administrative privileges or that the request is legitimate via nonces, an unauthenticated attacker can trigger the deletion of stored data.

2. Attack Vector Analysis

  • Vulnerable Function: wpl_data_req_process_delete()
  • Entry Point: Likely an AJAX action or an admin_init hook. Given the "unauthenticated" description, it is either registered via wp_ajax_nopriv_ or triggered during admin_init (which runs for all users, including unauthenticated ones, when accessing /wp-admin/admin-ajax.php).
  • Required Parameters (Inferred):
    • action: The AJAX action name (likely wpl_data_req_process_delete or similar).
    • id or request_id: The ID of the data request to be deleted.
  • Authentication: None (Unauthenticated).
  • Preconditions: There must be existing data requests or records in the plugin's database tables for the deletion to have a visible effect.

3. Code Flow (Inferred)

  1. Request Initiation: An HTTP request is sent to /wp-admin/admin-ajax.php.
  2. Hook Execution: WordPress triggers admin_init or the registered wp_ajax_ / wp_ajax_nopriv_ action.
  3. Function Call: The plugin's logic routes the request to wpl_data_req_process_delete().
  4. Vulnerability Point: Inside wpl_data_req_process_delete(), the code likely retrieves a record ID from $_GET or $_POST and proceeds to call a deletion method (e.g., $wpdb->delete(...)) without:
    • Calling current_user_can( 'manage_options' ).
    • Verifying a nonce using check_admin_referer() or wp_verify_nonce().
  5. Sink: The database record is removed.

4. Nonce Acquisition Strategy

According to the vulnerability description, the primary issue is Missing Authorization. This often implies that even if a nonce is present, the function fails to check the user's capability. However, if the function is unauthenticated and uses a nonce, we must find where it's leaked.

  1. Identify Shortcodes: Check if the plugin uses shortcodes to display data request forms.
    • grep -rn "add_shortcode" .
  2. Create Test Page:
    • wp post create --post_type=page --post_status=publish --post_title="GDPR Request" --post_content='[shortcode_found]'
  3. Extract Nonce (if needed):
    • Navigate to the page and use browser_eval to look for localized script data:
    • browser_eval("window.wpl_cookie_consent_data?.nonce") (Inferred JS variable name).

Note: If the function is hooked to admin_init and lacks any check_admin_referer, no nonce is required.

5. Exploitation Strategy

The goal is to delete a data request record unauthentically.

  1. Target URL: http://localhost:8080/wp-admin/admin-ajax.php (or via admin_init on any admin page).
  2. Method: POST or GET (depending on how the plugin reads parameters).
  3. Payload (Inferred):
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    action=wpl_data_req_process_delete&id=1
    
  4. Step-by-Step:
    • Identify the correct action name and parameter name (e.g., id, request_id, delete_id).
    • Identify if the trigger is an AJAX action or an admin_init listener looking for specific $_GET parameters.
    • Send the request using the http_request tool.

6. Test Data Setup

  1. Enable Data Requests: Ensure the plugin's GDPR/CCPA request feature is active in the settings.
  2. Generate a Request: As a visitor (unauthenticated), submit a "Data Deletion Request" through the plugin's frontend form (often found on a Privacy Policy page or via a shortcode).
  3. Confirm Request Exists:
    • wp db query "SELECT * FROM wp_posts WHERE post_type='cli_data_request'" (Post type is an inference based on typical plugin naming).
    • Alternatively, check plugin-specific tables: wp db query "SHOW TABLES LIKE '%wpl_%'" followed by a SELECT on likely tables.

7. Expected Results

  • Response: The server should return a success message (e.g., 1, {"success":true}, or a redirect) even when the requester is not logged in.
  • Impact: The targeted data request record is permanently removed from the database.

8. Verification Steps

  1. Check Database: Run the same SQL query used in "Test Data Setup" to verify the record with the targeted ID no longer exists.
    • wp db query "SELECT count(*) FROM [TABLE_NAME] WHERE id=1"
  2. Admin UI Check: Log in as an administrator and navigate to the "Data Requests" or "Cookie Law Info" section to verify the request is gone from the management dashboard.

9. Alternative Approaches

  • Parameter Fuzzing: If id does not work, try request_id, record_id, or cli_id.
  • Method Swap: If POST fails, try the request as a GET request to /wp-admin/admin-ajax.php?action=wpl_data_req_process_delete&id=1.
  • Bulk Deletion: Check if the function accepts an array of IDs (e.g., id[]=1&id[]=2) for mass data deletion.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Cookie Notice for GDPR, CCPA & ePrivacy Consent plugin is vulnerable to unauthenticated data deletion because the wpl_data_req_process_delete() function lacks capability checks and nonce verification. An attacker can exploit this to delete GDPR/CCPA data requests by sending a crafted request to the WordPress admin-ajax.php endpoint or an admin initialization hook.

Vulnerable Code

// File: gdpr-cookie-consent/admin/class-cookie-law-info-admin.php (inferred path)

public function wpl_data_req_process_delete() {
    if ( isset( $_GET['id'] ) ) {
        $id = intval( $_GET['id'] );
        // The code fails to call current_user_can('manage_options') here
        // The code fails to verify a nonce via check_admin_referer()
        $this->delete_data_request( $id );
        wp_safe_redirect( admin_url( 'admin.php?page=cookie-law-info-data-requests' ) );
        exit;
    }
}

Security Fix

--- a/admin/class-cookie-law-info-admin.php
+++ b/admin/class-cookie-law-info-admin.php
@@ -100,6 +100,10 @@
 public function wpl_data_req_process_delete() {
-    if ( isset( $_GET['id'] ) ) {
+    if ( isset( $_GET['id'] ) && isset( $_GET['_wpnonce'] ) ) {
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
+        }
+        check_admin_referer( 'wpl_delete_request', '_wpnonce' );
         $id = intval( $_GET['id'] );
         $this->delete_data_request( $id );

Exploit Outline

The exploit targets the missing authorization in the plugin's data request management logic. 1. Target Endpoint: The vulnerability is reachable via /wp-admin/admin-ajax.php or by triggering an admin_init hook (which fires for all users, including unauthenticated ones, when accessing /wp-admin/). 2. Action Identification: The attacker uses the 'wpl_data_req_process_delete' action, typically passed via the 'action' parameter. 3. Payload Construction: A GET or POST request is sent with the 'id' parameter set to the ID of the GDPR/CCPA request record to be deleted. Example: /wp-admin/admin-ajax.php?action=wpl_data_req_process_delete&id=5. 4. Authentication: No authentication or cookies are required, as the function lacks capability checks. No nonce is required because the function fails to perform nonce verification.

Check if your site is affected.

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