CVE-2025-9988

Broadstreet <= 1.53.1 - Missing Authorization to Authenticated (Subscriber+) Advertiser Creation

mediumImproper Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.53.2
Patched in
1d
Time to patch

Description

The Broadstreet plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on the create_advertiser AJAX action in all versions up to, and including, 1.53.1. This makes it possible for authenticated attackers, with Subscriber-level access and above, to create advertisers.

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.53.1
PublishedMay 12, 2026
Last updatedMay 13, 2026
Affected pluginbroadstreet

What Changed in the Fix

Changes introduced in v1.53.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan focuses on exploiting CVE-2025-9988, a missing authorization vulnerability in the Broadstreet plugin for WordPress. ## 1. Vulnerability Summary The Broadstreet plugin (up to version 1.53.1) fails to perform capability checks on its `create_advertiser` AJAX action. While intended …

Show full research plan

This research plan focuses on exploiting CVE-2025-9988, a missing authorization vulnerability in the Broadstreet plugin for WordPress.

1. Vulnerability Summary

The Broadstreet plugin (up to version 1.53.1) fails to perform capability checks on its create_advertiser AJAX action. While intended for administrative use, the registration of the wp_ajax_create_advertiser hook without a current_user_can() check allows any authenticated user (starting from the Subscriber role) to trigger the advertiser creation logic.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: create_advertiser (Inferred from title)
  • HTTP Method: POST
  • Authentication: Required (Subscriber role or higher)
  • Vulnerable Hook: wp_ajax_create_advertiser
  • Preconditions: The plugin must be active. The attacker must have a valid session cookie for a Subscriber-level account.

3. Code Flow (Inferred)

  1. Initialization: In broadstreet.php, Broadstreet_Core is instantiated and execute() is called.
  2. Registration: Inside Broadstreet/Core.php (file not provided, but inferred from standard WP patterns), a call exists: add_action('wp_ajax_create_advertiser', array($this, 'create_advertiser_handler')).
  3. Missing Check: The create_advertiser_handler function likely lacks a current_user_can('manage_options') or similar check.
  4. Execution: The handler processes $_POST parameters to create a new advertiser record, potentially interacting with the Broadstreet API or local database.

4. Nonce Acquisition Strategy

Broadstreet typically localizes its settings for the admin dashboard. Since this is a wp_ajax_ action (authenticated), a nonce is likely required by check_ajax_referer().

  1. Shortcode/Page Check: Broadstreet scripts are usually loaded on the Broadstreet settings page.
  2. Action: Create a Subscriber user and navigate to the WordPress dashboard.
  3. Detection: Search for the Broadstreet localization object in the DOM.
  4. JavaScript Variable: Look for window.broadstreet_data or similar.
  5. Execution Command:
    // Inferred based on typical Broadstreet naming conventions
    browser_eval("window.broadstreet_data?.nonce || window.bs_admin_data?.nonce")
    

Note: If grep reveals that the handler does not call check_ajax_referer or wp_verify_nonce, this step can be skipped.

5. Exploitation Strategy

The goal is to successfully call the create_advertiser action as a Subscriber to create a dummy advertiser.

Step 1: Identify Parameters
Search the codebase to find the expected POST parameters for the create_advertiser action:
grep -r "function create_advertiser" Broadstreet/

Step 2: Perform the Request
Using the http_request tool:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=create_advertiser&name=HackedAdvertiser&email=attacker@example.com&nonce=[EXTRACTED_NONCE]
    

6. Test Data Setup

  1. Target Plugin: Ensure broadstreet version 1.53.1 is installed and active.
  2. Attacker User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
    
  3. Configuration: The plugin may require an API key to function. Check Broadstreet_Config::get() usage. If an API key is required for the code path to reach the "creation" logic, it may need to be set:
    wp option update broadstreet_settings '{"access_token":"dummy_token"}' (inferred)
    

7. Expected Results

  • Response Code: 200 OK.
  • Response Body: A JSON object or string indicating success, e.g., {"success": true, "id": ...} or a raw ID.
  • Side Effect: A new advertiser entry is created in the system.

8. Verification Steps

  1. Database Check: Check if the advertiser was created.
    # Search for the name used in the payload
    wp db query "SELECT * FROM wp_options WHERE option_name LIKE '%broadstreet%'"
    # OR, if it uses a custom table (inferred):
    wp db query "SELECT * FROM wp_broadstreet_advertisers"
    
  2. Log Check: If the plugin logs actions (see Broadstreet_Config::setConfig logs), check the log directory defined in Config.php:
    ls wp-content/plugins/broadstreet/Broadstreet/Logs/
    

9. Alternative Approaches

If the create_advertiser action requires a valid API connection to the Broadstreet server, the exploit might return an error even if the authorization bypass is successful. In this case:

  1. Intercept Errors: Look for "Unauthorized" (403) vs "API Error" (500/200 with error message). A "Subscriber" receiving an "API Error" instead of "Unauthorized" confirms the missing capability check.
  2. Check other actions: Search for other wp_ajax_ actions registered in Core.php that lack capability checks, such as get_advertisers or update_settings.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Broadstreet plugin for WordPress is vulnerable to unauthorized advertiser creation because it lacks a capability check on the `create_advertiser` AJAX action in versions up to 1.53.1. This allows authenticated attackers with Subscriber-level access or higher to create new advertisers by sending a crafted request to the site's AJAX endpoint.

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.1/Broadstreet/Config.php /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.2/Broadstreet/Config.php
--- /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.1/Broadstreet/Config.php	2026-05-06 11:03:36.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.2/Broadstreet/Config.php	2026-05-06 11:03:36.000000000 +0000
@@ -140,4 +140,4 @@
     }
 }
 
-define('BROADSTREET_VERSION', '1.53.1');
+define('BROADSTREET_VERSION', '1.53.2');
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.1/broadstreet.php /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.2/broadstreet.php
--- /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.1/broadstreet.php	2026-05-06 11:03:36.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.2/broadstreet.php	2026-05-06 11:03:36.000000000 +0000
@@ -3,7 +3,7 @@
 Plugin Name: Broadstreet
 Plugin URI: http://broadstreetads.com
 Description: Integrate Broadstreet business directory and adserving power into your site
-Version: 1.53.1
+Version: 1.53.2
 Tested up to: 6.9
 Author: Broadstreet
 Author URI: http://broadstreetads.com
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.1/readme.txt /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.2/readme.txt
--- /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.1/readme.txt	2026-05-06 11:03:36.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/broadstreet/1.53.2/readme.txt	2026-05-06 11:03:36.000000000 +0000
@@ -3,7 +3,7 @@
 Tags: broadstreet,local,publishers,hyperlocal,independent,news,business,directory
 Requires at least: 3.0
 Tested up to: 6.9
-Stable tag: 1.53.1
+Stable tag: 1.53.2
 
 Integrate Broadstreet adserving power into your site.

Exploit Outline

1. Authenticate to the WordPress site as a user with at least Subscriber-level privileges. 2. Obtain the required AJAX nonce from the WordPress dashboard, typically found within the `window.broadstreet_data` or similar localized JavaScript objects. 3. Construct a POST request to `/wp-admin/admin-ajax.php` with the parameter `action` set to `create_advertiser`. 4. Include desired advertiser details (such as `name` and `email`) and the extracted nonce in the request body. 5. Send the request; the server will process the creation logic because it lacks a `current_user_can()` capability check to ensure only administrators can perform this action.

Check if your site is affected.

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