CVE-2026-9619

Reviews and Rating <= 1.1.4 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Modification via sync_reviews AJAX Action

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Reviews and Rating – Docplanner plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 1.1.4. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with subscriber-level access and above, to trigger outbound scraping of external websites and write scraped review data into the wp_dp_reviews database table, as well as send feature-request emails from the site administrator's email address.

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.1.4
PublishedJune 23, 2026
Last updatedJune 24, 2026
Research Plan
Unverified

I cannot fulfill your request to create an exploitation research plan or provide specific HTTP payloads for CVE-2026-9619 or the "Reviews and Rating – Docplanner" plugin. Providing actionable instructions for exploiting vulnerabilities on specific software targets poses significant security risks. …

Show full research plan

I cannot fulfill your request to create an exploitation research plan or provide specific HTTP payloads for CVE-2026-9619 or the "Reviews and Rating – Docplanner" plugin. Providing actionable instructions for exploiting vulnerabilities on specific software targets poses significant security risks.

However, I can provide a general technical analysis of how "Missing Authorization" vulnerabilities occur in WordPress AJAX handlers and how developers can secure these endpoints against unauthorized access.

Understanding Missing Authorization in WordPress AJAX

In WordPress, AJAX actions are registered using two main hooks:

  1. wp_ajax_{action}: Runs for authenticated users.
  2. wp_ajax_nopriv_{action}: Runs for unauthenticated (logged-out) users.

A common security misconception is that registering an action only via the wp_ajax_ hook provides sufficient security. While it does restrict the action to logged-in users, it does not distinguish between user roles. A user with the "Subscriber" role (the lowest default privilege) can trigger any action registered with wp_ajax_ if no further checks are performed.

Vulnerability Mechanism

A "Missing Authorization" vulnerability occurs when a sensitive function is exposed via an AJAX handler but lacks internal checks to verify the user's permissions. In the context of the vulnerability you described, the sync_reviews action likely failed to verify if the requesting user had administrative privileges before performing sensitive operations like scraping external sites or sending emails.

Core Security Controls for AJAX Handlers

To secure an AJAX endpoint, developers must implement two distinct types of checks: Authentication/Authorization and Integrity/CSRF Protection.

1. Authorization (Capability Checks)

The primary defense against unauthorized access is the current_user_can() function. This check must be performed within the handler function itself.

  • Vulnerable Implementation:

    add_action('wp_ajax_sync_reviews', 'handle_sync_reviews');
    
    function handle_sync_reviews() {
        // VULNERABLE: No check to see IF the logged-in user 
        // has the right to perform this action.
        perform_sensitive_sync();
        wp_die();
    }
    
  • Secure Implementation:

    add_action('wp_ajax_sync_reviews', 'handle_sync_reviews');
    
    function handle_sync_reviews() {
        // SECURE: Verify the user has administrative capabilities
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Unauthorized', 403);
        }
        
        perform_sensitive_sync();
        wp_die();
    }
    

2. CSRF Protection (Nonce Verification)

Nonces (Number used ONCE) protect against Cross-Site Request Forgery (CSRF). While they verify that the request was intentionally sent from the site's interface, they are not a substitute for authorization. A Subscriber can often obtain a nonce from the dashboard and use it to authorize their own (otherwise unauthorized) requests.

  • Verification Method:
    Developers use check_ajax_referer('action_string', 'query_arg') or wp_verify_nonce().

    function handle_sync_reviews() {
        // CSRF Check
        check_ajax_referer('sync_reviews_nonce', 'security');
    
        // Authorization Check (Essential)
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Unauthorized', 403);
        }
        // ...
    }
    

Common Pitfalls in AJAX Security

  1. Confusing Nonces with Authorization: Developers sometimes assume that because a request has a valid nonce, the user is authorized. This is incorrect; nonces only prove intent and origin.
  2. Relying on Hook Type: Assuming wp_ajax_ is secure because it requires a login. It only prevents anonymous access, not horizontal or vertical privilege escalation.
  3. Ignoring Return Values: Using wp_verify_nonce() but not checking the return value or failing to die()/exit upon failure.
  4. Implicit Trust in Input: Failing to sanitize or validate parameters (like URLs for scraping) even if the user is authorized, which can lead to other issues like SSRF (Server-Side Request Forgery).

For further information on securing WordPress plugins, I recommend reviewing the WordPress Plugin Handbook's Security section and the OWASP Top 10 guidelines.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Reviews and Rating – Docplanner plugin for WordPress fails to implement authorization checks on the 'sync_reviews' AJAX action. This allows any authenticated user, such as a subscriber, to trigger external site scraping, modify the plugin's database tables, and dispatch emails from the site administrator's address.

Vulnerable Code

// reviews-and-rating-docplanner/admin/class-reviews-and-rating-docplanner-admin.php (approximate location)

add_action('wp_ajax_sync_reviews', array($this, 'sync_reviews'));

public function sync_reviews() {
    // Vulnerability: No check for user capabilities (e.g., current_user_can('manage_options'))
    // and often missing nonce verification (check_ajax_referer).

    $this->perform_scraping_logic();
    $this->update_database_reviews();
    $this->send_admin_email();

    wp_send_json_success();
}

Security Fix

--- a/admin/class-reviews-and-rating-docplanner-admin.php
+++ b/admin/class-reviews-and-rating-docplanner-admin.php
@@ -XX,XX +XX,XX @@
 public function sync_reviews() {
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
+    }
+
+    check_ajax_referer( 'dp_reviews_sync_nonce', 'security' );
+
     $this->perform_scraping_logic();

Exploit Outline

The exploit target is the WordPress AJAX endpoint. An attacker first authenticates as a low-privileged user (e.g., Subscriber). They then craft a POST request to '/wp-admin/admin-ajax.php' with the parameter 'action=sync_reviews'. Because the server-side handler fails to check 'current_user_can()', it executes the function logic. This results in the server performing outbound HTTP requests to scrape data, inserting that data into the 'wp_dp_reviews' table, and potentially triggering unauthorized emails from the administrator's account via the plugin's feature-request mechanism.

Check if your site is affected.

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