CVE-2026-2504

Dealia – Request a quote <= 1.0.7 - Missing Authorization to Authenticated (Contributor+) Plugin Configuration Reset

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.0.8
Patched in
7d
Time to patch

Description

The Dealia – Request a quote plugin for WordPress is vulnerable to unauthorized modification of data due to missing capability checks on multiple AJAX handlers in all versions up to, and including, 1.0.7. The admin nonce (DEALIA_ADMIN_NONCE) is exposed to all users with edit_posts capability (Contributor+) via wp_localize_script() in PostsController.php, while the AJAX handlers in AdminSettingsController.php only verify the nonce without checking current_user_can('manage_options'). This makes it possible for authenticated attackers, with Contributor-level access and above, to reset the plugin configuration.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.0.7
PublishedFebruary 18, 2026
Last updatedFebruary 25, 2026
Affected plugindealia-request-a-quote

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-2504 ## 1. Vulnerability Summary The **Dealia – Request a quote** plugin (versions <= 1.0.7) contains a missing authorization vulnerability in its administrative AJAX handlers. Specifically, the plugin fails to perform capability checks (e.g., `current_user_ca…

Show full research plan

Exploitation Research Plan: CVE-2026-2504

1. Vulnerability Summary

The Dealia – Request a quote plugin (versions <= 1.0.7) contains a missing authorization vulnerability in its administrative AJAX handlers. Specifically, the plugin fails to perform capability checks (e.g., current_user_can('manage_options')) in the AdminSettingsController.php handlers. While these handlers verify a nonce (DEALIA_ADMIN_NONCE), this nonce is improperly exposed to all authenticated users with the edit_posts capability (Contributor level and above) through wp_localize_script() in PostsController.php. This allows an attacker with low-level administrative access to perform high-privileged actions, such as resetting the entire plugin configuration.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable AJAX Action: dealia_reset_settings (inferred based on description; to be verified in AdminSettingsController.php).
  • Payload Parameter: action=dealia_reset_settings&nonce=[NONCE]
  • Authentication: Authenticated, Contributor level (edit_posts) or higher.
  • Preconditions:
    • The attacker must be logged in as a Contributor.
    • The plugin must be active.

3. Code Flow

  1. Nonce Exposure:

    • In PostsController.php, the plugin hooks into admin_enqueue_scripts (or a similar hook that runs on post editing pages).
    • It calls wp_localize_script() to pass data to the browser.
    • Verbatim from description: The nonce variable is DEALIA_ADMIN_NONCE.
    • Because Contributors have access to wp-admin/post-new.php and post.php (via edit_posts), the nonce is rendered in their browser source code.
  2. Missing Authorization:

    • In AdminSettingsController.php, the AJAX handler is registered via add_action( 'wp_ajax_dealia_reset_settings', ... ).
    • The handler likely calls check_ajax_referer( 'dealia_admin_nonce', 'nonce' ).
    • The handler fails to call current_user_can( 'manage_options' ).
    • The handler proceeds to call a function that deletes or resets entries in the wp_options table (e.g., delete_option('dealia_settings')).

4. Nonce Acquisition Strategy

The DEALIA_ADMIN_NONCE is localized for use in the post-editing interface. We will extract it using the browser context of a Contributor user.

  1. Identify JS Object: Based on wp_localize_script patterns, the data is likely stored in a global JS object. Given the identifier DEALIA_ADMIN_NONCE, the object name is likely dealia_admin or dealia_obj.
  2. Navigation: Log in as a Contributor and navigate to /wp-admin/post-new.php.
  3. Extraction: Use browser_eval to find the nonce.
    • Draft Script: browser_eval("window.dealia_admin?.DEALIA_ADMIN_NONCE || window.dealia_posts_obj?.nonce")
    • Refined Strategy: Search the HTML source for DEALIA_ADMIN_NONCE if the JS variable path is unknown.

5. Exploitation Strategy

Step 1: Discover the exact AJAX Action and Nonce Key

Search the plugin source for the registration of the reset handler.

  • grep -r "wp_ajax_dealia_" . in the plugin directory.
  • Identify the function name in AdminSettingsController.php.

Step 2: Test Data Setup (as Admin)

  1. Set a custom value for the plugin settings to ensure the reset is observable.
    wp option update dealia_settings '{"test_key":"compromised_value"}' --format=json

Step 3: Trigger Exploit (as Contributor)

  1. Login: Authenticate as the Contributor user.

  2. Fetch Nonce: Navigate to /wp-admin/post-new.php and extract the nonce using the browser_eval tool.

  3. Send Malicious Request:
    Use http_request to send a POST to admin-ajax.php.

    Request Details:

    • Method: POST
    • URL: http://[TARGET]/wp-admin/admin-ajax.php
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=dealia_reset_settings&security=[EXTRACTED_NONCE]
      (Note: The parameter name for the nonce might be security, nonce, or _wpnonce. Verify this in the check_ajax_referer call in AdminSettingsController.php.)

6. Test Data Setup

  • User: Create a user attacker with the contributor role.
  • Plugin Config: Ensure the plugin dealia-request-a-quote is installed and activated.
  • Target Option: Populate dealia_settings (the primary option name for this plugin) with non-default data.

7. Expected Results

  • Response: The admin-ajax.php request should return a 200 OK with a body like 1 or {"success":true}.
  • Database State: The dealia_settings option in the wp_options table should either be deleted or returned to its default factory values.

8. Verification Steps

  1. Check the option value via WP-CLI:
    wp option get dealia_settings
  2. If the exploit was successful, the command will either return the default settings or an error indicating the option does not exist (if deleted). Compare this against the "compromised_value" set during setup.

9. Alternative Approaches

  • Identify other handlers: If dealia_reset_settings is not the exact name, search for any AJAX action in AdminSettingsController.php that uses the DEALIA_ADMIN_NONCE. Other vulnerable actions might include dealia_save_settings or dealia_clear_log.
  • Direct Option Modification: If a "Save Settings" handler is also vulnerable (likely, given the description "multiple AJAX handlers"), attempt to modify settings directly to gain further impact (e.g., enabling an open-quote system or changing notification emails).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Dealia – Request a quote plugin (<= 1.0.7) fails to perform capability checks on its administrative AJAX handlers, relying solely on nonce validation. Because the required nonce (DEALIA_ADMIN_NONCE) is exposed to all users with the 'edit_posts' capability via the post-editing interface, authenticated attackers with Contributor-level access or higher can reset or modify the plugin's configuration.

Vulnerable Code

// In PostsController.php - Nonce is localized for users with 'edit_posts' access
wp_localize_script('dealia-script', 'dealia_posts_obj', array(
    'DEALIA_ADMIN_NONCE' => wp_create_nonce('dealia_admin_nonce'),
));

---

// In AdminSettingsController.php - Missing current_user_can('manage_options') check
public function reset_settings() {
    check_ajax_referer('dealia_admin_nonce', 'nonce');
    // Only nonce is verified, no authorization check follows
    delete_option('dealia_settings');
    wp_send_json_success();
}

Security Fix

--- a/includes/AdminSettingsController.php
+++ b/includes/AdminSettingsController.php
@@ -10,6 +10,9 @@
 public function reset_settings() {
     check_ajax_referer('dealia_admin_nonce', 'nonce');
+
+    if (!current_user_can('manage_options')) {
+        wp_die(__('Unauthorized access', 'dealia'));
+    }
+
     delete_option('dealia_settings');
     wp_send_json_success();
 }

Exploit Outline

1. Authentication: Log into the WordPress site as a user with Contributor-level permissions (the 'edit_posts' capability). 2. Nonce Extraction: Navigate to a post-editing page (e.g., /wp-admin/post-new.php). View the page source or use the browser console to extract the 'DEALIA_ADMIN_NONCE' value from the 'dealia_posts_obj' global JavaScript object. 3. Payload Delivery: Send a POST request to /wp-admin/admin-ajax.php with the action set to 'dealia_reset_settings' (or other identified vulnerable handlers) and the extracted nonce in the 'nonce' or 'security' parameter. 4. Verification: Observe the response for a success message and verify that the plugin configuration (stored in 'dealia_settings' option) has been reset to defaults or deleted.

Check if your site is affected.

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