CVE-2026-39606

BizReview <= 1.5.14 - Missing Authorization

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

Description

The BizReview plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.5.14. This makes it possible for unauthenticated attackers to perform an unauthorized action.

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<=1.5.14
PublishedFebruary 3, 2026
Last updatedApril 15, 2026
Affected pluginbizreview
Research Plan
Unverified

This research plan focuses on identifying and exploiting a Missing Authorization vulnerability in the **BizReview** plugin (<= 1.5.14). The vulnerability allows unauthenticated attackers to perform actions that should be restricted to administrators, typically through unprotected AJAX handlers. ###…

Show full research plan

This research plan focuses on identifying and exploiting a Missing Authorization vulnerability in the BizReview plugin (<= 1.5.14). The vulnerability allows unauthenticated attackers to perform actions that should be restricted to administrators, typically through unprotected AJAX handlers.

1. Vulnerability Summary

The BizReview plugin fails to implement proper capability checks (e.g., current_user_can( 'manage_options' )) in one or more of its AJAX handler functions. While it may or may not implement a nonce check, the lack of a server-side authorization check allows any user (or unauthenticated visitor, if wp_ajax_nopriv_ is used) to execute the function's logic. Based on the plugin's purpose, this likely involves modifying plugin settings, managing reviews, or interacting with Google Place API configurations.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Actions (Inferred):
    • bizreview_save_settings
    • bizreview_update_options
    • bizreview_import_reviews
  • Parameters: action, security/nonce (if required), and configuration arrays (e.g., options, settings).
  • Authentication: Unauthenticated (via wp_ajax_nopriv_ hooks) or Subscriber-level (via wp_ajax_ hooks if registration is open).
  • Preconditions: The plugin must be active. If a nonce is required, it must be extractable from the frontend or a specific shortcode-enabled page.

3. Code Flow (Inferred Trace)

  1. Entry Point: An AJAX request is sent to admin-ajax.php with a specific action parameter (e.g., action=bizreview_save_settings).
  2. Hook Registration: The plugin registers the action in its main file or an admin/ajax class:
    add_action( 'wp_ajax_nopriv_bizreview_save_settings', 'bizreview_save_settings_callback' ); (or similar).
  3. Vulnerable Function: The callback function (e.g., bizreview_save_settings_callback) is invoked.
  4. Authorization Failure: The function performs logic (like update_option()) without calling current_user_can().
  5. Sink: WordPress database options are updated or sensitive actions are performed.

4. Nonce Acquisition Strategy

If the AJAX handler uses check_ajax_referer or wp_verify_nonce, we must obtain a valid nonce.

  1. Identify Shortcode: Search for shortcodes in the plugin:
    grep -r "add_shortcode" /var/www/html/wp-content/plugins/bizreview/
  2. Locate Localization: Find where the plugin passes data to JS:
    grep -r "wp_localize_script" /var/www/html/wp-content/plugins/bizreview/
    Look for variable names like bizreview_vars, bizreview_ajax, or br_ajax_obj.
  3. Setup Page:
    Create a post containing the identified shortcode:
    wp post create --post_type=page --post_status=publish --post_content='[bizreview_shortcode]' (Replace with actual shortcode).
  4. Extraction:
    Navigate to the newly created page and use browser_eval to extract the nonce:
    browser_eval("window.bizreview_vars?.nonce") (Replace bizreview_vars and nonce with actual keys found in the source).

5. Exploitation Strategy

The goal is to demonstrate unauthorized configuration change (e.g., changing the Google API key or internal plugin settings).

Request Details:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Payload:
    action=bizreview_save_settings&security=[NONCE]&bizreview_options[google_api_key]=EXPLOITED_API_KEY&bizreview_options[some_critical_setting]=1
    
    (Note: Parameter names like bizreview_options are inferred and must be confirmed via grep).

Grep commands to confirm parameters:

# Find the callback function for AJAX actions
grep -r "wp_ajax_" /var/www/html/wp-content/plugins/bizreview/

# Examine the callback for the logic and parameter names
# Example: if action is bizreview_save_settings, find:
# function bizreview_save_settings() { ... }

6. Test Data Setup

  1. Plugin Installation: Ensure bizreview version 1.5.14 is installed and activated.
  2. Discovery: Run a grep to find the specific vulnerable action:
    grep -r "update_option" /var/www/html/wp-content/plugins/bizreview/ | grep -v "install"
    This helps identify which AJAX handlers are actually writing to the database.

7. Expected Results

  • HTTP Response: A 200 OK response, often containing {"success":true} or 1.
  • Database Change: The plugin's settings in the wp_options table will be updated with the attacker-supplied values.

8. Verification Steps

After the http_request, verify the state change using WP-CLI:

# Check if the targeted option was changed
wp option get bizreview_options --format=json

If the output contains EXPLOITED_API_KEY, the Missing Authorization is confirmed.

9. Alternative Approaches

  • If wp_ajax_nopriv is not present: Attempt the exploit as a Subscriber user. If wp_ajax_ is used without current_user_can, any logged-in user can exploit it.
  • Endpoint Hunting: If admin-ajax.php is not the vector, check for custom REST API routes:
    grep -r "register_rest_route" /var/www/html/wp-content/plugins/bizreview/
    Check the permission_callback for __return_true.
  • Direct Option Update: Some plugins use a pattern where they hook into init or admin_init and check for specific $_POST keys.
    grep -r "add_action.*admin_init" /var/www/html/wp-content/plugins/bizreview/
    Note: admin_init triggers for any user visiting /wp-admin/admin-ajax.php, making it a common source of authorization bypasses.
Research Findings
Static analysis — not yet PoC-verified

Summary

The BizReview plugin for WordPress is vulnerable to unauthorized modification of settings due to a missing capability check on its AJAX handler functions. This allows unauthenticated or low-privileged attackers to perform administrative actions, such as updating plugin configurations or changing API keys, by sending requests to admin-ajax.php.

Exploit Outline

1. Identify the vulnerable AJAX action registered via wp_ajax_ or wp_ajax_nopriv_ hooks (e.g., bizreview_save_settings). 2. If the handler requires a nonce, locate where the plugin localizes script variables (e.g., using wp_localize_script) and extract the nonce from a page where the plugin is active. 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to the target function and 'security' or 'nonce' set to the extracted value. 4. Include payload parameters representing the settings to be changed (e.g., bizreview_options[google_api_key]=EXPLOITED). 5. Verify the configuration change via a public page or WP-CLI, confirming that the lack of current_user_can() allowed the unauthorized update.

Check if your site is affected.

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