WP Blockade <= 0.9.14 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Shortcode Execution via 'shortcode' Parameter
Description
The WP Blockade plugin for WordPress is vulnerable to Missing Authorization in all versions up to and including 0.9.14. The plugin registers an admin_post action hook 'wp-blockade-shortcode-render' that maps to the render_shortcode_preview() function. This function lacks any capability check (current_user_can()) and nonce verification, allowing any authenticated user to execute arbitrary WordPress shortcodes. The function takes a user-supplied 'shortcode' parameter from $_GET, passes it through stripslashes(), and directly executes it via do_shortcode(). This makes it possible for authenticated attackers, with Subscriber-level access and above, to execute arbitrary shortcodes, which could lead to information disclosure, privilege escalation, or other impacts depending on what shortcodes are registered on the site (e.g., shortcodes from other plugins that display sensitive data, perform actions, or include files).
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NTechnical Details
This research plan outlines the steps required to demonstrate the arbitrary shortcode execution vulnerability in the WP Blockade plugin. ## 1. Vulnerability Summary The **WP Blockade** plugin (up to version 0.9.14) fails to implement authorization and CSRF protection on its shortcode rendering prev…
Show full research plan
This research plan outlines the steps required to demonstrate the arbitrary shortcode execution vulnerability in the WP Blockade plugin.
1. Vulnerability Summary
The WP Blockade plugin (up to version 0.9.14) fails to implement authorization and CSRF protection on its shortcode rendering preview functionality. The plugin registers an admin_post hook named wp-blockade-shortcode-render, which triggers the render_shortcode_preview() function. Because this function does not verify user capabilities (current_user_can()) or check for a valid security nonce, any authenticated user—including those with Subscriber-level privileges—can call this endpoint. The function directly passes user input from the shortcode GET parameter into the WordPress do_shortcode() function, leading to arbitrary shortcode execution.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-post.php - Action Hook:
wp-blockade-shortcode-render(registered viaadmin_post_wp-blockade-shortcode-render) - HTTP Method:
GET(as per vulnerability description) - Vulnerable Parameter:
shortcode - Authentication: Required (Subscriber or higher)
- Permissions: None (Missing
current_user_cancheck) - CSRF Protection: None (Missing
check_admin_refererorwp_verify_noncecheck)
3. Code Flow (Inferred)
- Entry Point: An authenticated user makes a GET request to
/wp-admin/admin-post.php?action=wp-blockade-shortcode-render&shortcode=[payload]. - Hook Execution: WordPress core (
wp-admin/admin-post.php) detects theactionand triggers theadmin_post_wp-blockade-shortcode-renderhook. - Handler Call: The plugin's
render_shortcode_preview()function is called. - Processing:
- The function retrieves
$_GET['shortcode']. - It applies
stripslashes()to the input. - Sink: It calls
echo do_shortcode( stripslashes( $_GET['shortcode'] ) );.
- The function retrieves
- Execution: WordPress parses and executes the provided shortcode. If the shortcode is registered by WordPress core or any installed plugin, it executes its respective callback.
4. Nonce Acquisition Strategy
According to the vulnerability description, the function completely lacks nonce verification.
- Nonce Requirement: None.
- Bypass Strategy: No bypass is necessary as no check exists. An attacker only needs a valid session cookie for a Subscriber-level user.
5. Exploitation Strategy
The goal is to prove that a Subscriber user can execute a shortcode that they would normally not be able to trigger, or one that returns sensitive data.
Step-by-Step Plan:
- Login as Subscriber: Use the
http_requesttool to authenticate as a Subscriber user and capture the session cookies. - Identify Target Shortcode: We will use a WordPress core shortcode that generates distinct HTML to prove execution. The
[caption]shortcode is ideal because it wraps content in a specificdivorfiguretag. - Construct Payload:
- Shortcode:
[caption width="1" caption="EXPLOIT_SUCCESS"]Vulnerable[/caption] - URL Encoded:
%5Bcaption%20width%3D%221%22%20caption%3D%22EXPLOIT_SUCCESS%22%5DVulnerable%5B%2Fcaption%5D
- Shortcode:
- Execute Request: Send an authenticated GET request to the
admin-post.phpendpoint.
Request Details:
- URL:
http://localhost:8080/wp-admin/admin-post.php?action=wp-blockade-shortcode-render&shortcode=%5Bcaption%20width%3D%221%22%20caption%3D%22EXPLOIT_SUCCESS%22%5DVulnerable%5B%2Fcaption%5D - Method:
GET - Headers: Must include the
Cookieheader obtained during login.
6. Test Data Setup
- Plugin Installation: Ensure
wp-blockadeversion 0.9.14 is installed and active. - User Creation: Create a Subscriber user:
- Username:
low_priv_user - Password:
password123 - Role:
subscriber
wp user create low_priv_user low_priv@example.com --role=subscriber --user_pass=password123 - Username:
7. Expected Results
- HTTP Status:
200 OK - Response Body: Should contain the rendered HTML for the caption shortcode, specifically looking for the string
EXPLOIT_SUCCESS. - Response Example:
<div id="attachment_..." style="width: 11px" class="wp-caption alignnone"> <p class="wp-caption-text">EXPLOIT_SUCCESS</p> </div>
8. Verification Steps
- Check Response: Confirm that the response body contains
EXPLOIT_SUCCESSand thewp-captionclass. - Access Control Verification: Attempt the same request without a session cookie. It should either fail or behave differently (usually redirecting to login), confirming that while authentication is checked by WordPress core for
admin_post, the plugin fails to check authorization (capabilities). - Role Check: Verify the
low_priv_useris indeed a Subscriber:wp user get low_priv_user --field=roles
9. Alternative Approaches
If admin-post.php requires a specific referrer or behaves unexpectedly with GET, attempt the following:
- POST Request: Change the method to
POSTand send the parameters in the body:action=wp-blockade-shortcode-rendershortcode=[caption ...]
- Information Disclosure PoC: If other plugins are present (e.g., WooCommerce, MemberPress), try to execute shortcodes that reveal information, such as
[woocommerce_my_account]or plugin-specific "user info" shortcodes, to demonstrate high impact. - Cross-Site Scripting (XSS): If any registered shortcode reflects attributes without proper escaping (common in older plugins), this vulnerability can be used as a vector for Reflected XSS targeting other authenticated users.
Summary
The WP Blockade plugin for WordPress (<= 0.9.14) is vulnerable to arbitrary shortcode execution because its shortcode rendering endpoint lacks authorization and nonce checks. This allows any authenticated user, including those with Subscriber-level privileges, to execute any registered shortcode on the site by providing it via a GET parameter.
Vulnerable Code
// From inferred plugin logic add_action( 'admin_post_wp-blockade-shortcode-render', 'render_shortcode_preview' ); function render_shortcode_preview() { // Function lacks current_user_can() and check_admin_referer() checks if ( isset( $_GET['shortcode'] ) ) { echo do_shortcode( stripslashes( $_GET['shortcode'] ) ); } exit; }
Security Fix
@@ -1,5 +1,9 @@ function render_shortcode_preview() { + if ( ! current_user_can( 'edit_posts' ) ) { + wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); + } + check_admin_referer( 'wp-blockade-render-action', 'security' ); if ( isset( $_GET['shortcode'] ) ) { echo do_shortcode( stripslashes( $_GET['shortcode'] ) ); }
Exploit Outline
1. Authenticate to the WordPress site as a user with minimal privileges (Subscriber). 2. Construct a GET request targeting the admin-post.php endpoint: `/wp-admin/admin-post.php?action=wp-blockade-shortcode-render`. 3. Add a 'shortcode' parameter to the request containing the shortcode to be executed (e.g., `[caption width="1" caption="EXPLOIT_SUCCESS"]Vulnerable[/caption]`). 4. Submit the request while including the valid authentication session cookies. 5. Verify execution by observing the rendered HTML output of the shortcode in the server's response body.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.