QR Redirector <= 2.0.3 - Missing Authorization
Description
The QR Redirector plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.0.3. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
This research plan focuses on **CVE-2026-24545**, a Missing Authorization vulnerability in the **QR Redirector** plugin for WordPress. ### 1. Vulnerability Summary The **QR Redirector** plugin (<= 2.0.3) fails to implement proper capability checks (e.g., `current_user_can()`) in one or more of its …
Show full research plan
This research plan focuses on CVE-2026-24545, a Missing Authorization vulnerability in the QR Redirector plugin for WordPress.
1. Vulnerability Summary
The QR Redirector plugin (<= 2.0.3) fails to implement proper capability checks (e.g., current_user_can()) in one or more of its AJAX handler functions. While these functions are registered via the wp_ajax_ hook (restricting access to authenticated users), they lack secondary authorization logic to ensure only administrators or users with the manage_options capability can execute them. This allows a user with Subscriber level permissions to perform administrative actions such as creating, modifying, or deleting redirects.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Method:
POST - Vulnerable Action:
qrr_save_redirect(inferred) orqrr_delete_redirect(inferred). - Authentication: Required (Subscriber or higher).
- Payload Parameter:
action,nonce(if checked), and data parameters (e.g.,redirect_url,post_id). - Preconditions: An authenticated Subscriber-level account is required. The plugin must be active.
3. Code Flow (Inferred)
- Entry Point: An authenticated user sends a request to
admin-ajax.phpwith theactionparameter set to the vulnerable hook (likely prefixed withqrr_). - Hook Registration: The plugin registers the action:
add_action( 'wp_ajax_qrr_save_redirect', 'qrr_save_redirect_callback' );(inferred). - Vulnerable Function: The callback function (e.g.,
qrr_save_redirect_callback) executes. - Missing Check: The function likely calls
check_ajax_referer()to verify a CSRF nonce but fails to callcurrent_user_can( 'manage_options' ). - Sink: The function proceeds to update the database (e.g.,
update_post_metaor$wpdb->update) based on the user-supplied$_POSTdata.
4. Nonce Acquisition Strategy
If the plugin enforces a nonce check via check_ajax_referer, the nonce must be retrieved from the admin dashboard or a page where the plugin enqueues its scripts.
- Identify Localized Script: Search the plugin source for
wp_localize_script. Look for the variable name containing the nonce (e.g.,qrr_vars,qrr_settings). - Shortcode/Page Setup: If the nonce is only loaded on specific pages (like the redirect management page), identify the shortcode or admin menu slug.
- Extraction Script:
- Navigate to the WordPress dashboard as a Subscriber.
- Execute the following in the browser console:
browser_eval("window.qrr_vars?.nonce || window.qrr_obj?.ajax_nonce")(inferred identifiers).
- Bypass Check: If the code uses
check_ajax_referer( 'qrr_action', 'nonce', false )and fails to check the return value, the nonce can be any value.
5. Exploitation Strategy
This plan aims to modify an existing redirect or create a new one as a Subscriber.
Step 1: Authenticate as Subscriber
Perform a login request using http_request to obtain session cookies.
Step 2: Obtain the Nonce
Navigate to the plugin's settings or a page containing its interface to extract the nonce.
Step 3: Trigger the Vulnerable Action
Send a POST request to admin-ajax.php to modify a redirect.
- URL:
http://[target]/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
(Note: Parameter names likeaction=qrr_save_redirect&nonce=[NONCE]&id=[TARGET_POST_ID]&redirect_url=http://attacker.comidandredirect_urlare inferred based on plugin functionality and should be verified viagrepin the environment.)
6. Test Data Setup
- Install Plugin: Ensure QR Redirector v2.0.3 is installed and active.
- Create Target Redirect: As an Admin, create a redirect (e.g., "Google" ->
https://google.com). Note the Post ID of this redirect. - Create Attacker User: Create a user with the Subscriber role.
7. Expected Results
- Response: The server should return a successful JSON response (e.g.,
{"success":true}) or a1(typical for successful WordPress AJAX). - Impact: The redirect URL associated with the target ID should be changed to the attacker-controlled URL (
http://attacker.com).
8. Verification Steps
After the exploitation attempt, verify the change using WP-CLI:
# Check the post meta for the redirected URL
wp post meta list [TARGET_POST_ID]
# Or verify via a direct database query if stored in a custom table
wp db query "SELECT * FROM wp_posts WHERE post_type='qr_redirect' AND ID=[TARGET_POST_ID]"
9. Alternative Approaches
If qrr_save_redirect is not the correct action:
- Identify all AJAX hooks:
grep -r "wp_ajax_" wp-content/plugins/qr-redirector/ - Check for "Delete" actions:
Attempt to delete an admin-created redirect using an action likeqrr_delete_redirect. - Check for Settings Update:
Look for actions that update global plugin settings (e.g.,qrr_update_settings) which often lack authorization.
Summary
The QR Redirector plugin for WordPress (<= 2.0.3) lacks a capability check in its AJAX handler functions, which are registered via the wp_ajax_ hook. This vulnerability allows authenticated users with subscriber-level permissions or higher to perform unauthorized administrative actions, such as creating, modifying, or deleting redirects.
Exploit Outline
1. Authenticate as a Subscriber-level user. 2. Locate the security nonce used by the plugin, typically found by inspecting localized scripts (e.g., qrr_vars or qrr_settings) in the WordPress dashboard. 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to the vulnerable callback (e.g., qrr_save_redirect). 4. Include the retrieved nonce and the desired payload parameters (e.g., id=[TARGET_POST_ID] and redirect_url=http://attacker.com). 5. The server will process the request and update the redirect in the database because it fails to call current_user_can('manage_options') to verify permissions.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.