Broadstreet <= 1.53.1 - Missing Authorization to Authenticated (Subscriber+) Advertiser Creation
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:NTechnical Details
What Changed in the Fix
Changes introduced in v1.53.2
Source Code
WordPress.org SVNThis 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)
- Initialization: In
broadstreet.php,Broadstreet_Coreis instantiated andexecute()is called. - 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')). - Missing Check: The
create_advertiser_handlerfunction likely lacks acurrent_user_can('manage_options')or similar check. - Execution: The handler processes
$_POSTparameters 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().
- Shortcode/Page Check: Broadstreet scripts are usually loaded on the Broadstreet settings page.
- Action: Create a Subscriber user and navigate to the WordPress dashboard.
- Detection: Search for the Broadstreet localization object in the DOM.
- JavaScript Variable: Look for
window.broadstreet_dataor similar. - 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
- Target Plugin: Ensure
broadstreetversion 1.53.1 is installed and active. - Attacker User:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password - 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
- 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" - Log Check: If the plugin logs actions (see
Broadstreet_Config::setConfiglogs), check the log directory defined inConfig.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:
- 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.
- Check other actions: Search for other
wp_ajax_actions registered inCore.phpthat lack capability checks, such asget_advertisersorupdate_settings.
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
@@ -140,4 +140,4 @@ } } -define('BROADSTREET_VERSION', '1.53.1'); +define('BROADSTREET_VERSION', '1.53.2'); @@ -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 @@ -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.