Email Inquiry & Cart Options for WooCommerce <= 3.4.3 - Authenticated (Contributor+) Stored Cross-Site Scripting
Description
The Email Inquiry & Cart Options for WooCommerce plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 3.4.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=3.4.3This research plan focuses on identifying and exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the **Email Inquiry & Cart Options for WooCommerce** plugin. Since source files are not provided, this plan relies on the vulnerability description and common patterns found in WooCommerce e…
Show full research plan
This research plan focuses on identifying and exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the Email Inquiry & Cart Options for WooCommerce plugin. Since source files are not provided, this plan relies on the vulnerability description and common patterns found in WooCommerce extension plugins.
1. Vulnerability Summary
- Vulnerability: Authenticated (Contributor+) Stored XSS.
- Location: Likely within product-specific inquiry settings or plugin-wide settings that fail to sanitize input during save and fail to escape output during rendering.
- Cause: The plugin registers custom fields for WooCommerce products (e.g., custom button text, inquiry form headers) but does not apply
sanitize_text_fieldorwp_kseswhen saving metadata, and uses rawechoor similar output methods withoutesc_htmloresc_attron the frontend. - Impact: An attacker with Contributor-level access can inject malicious JavaScript. When an administrator or visitor views the affected product page or an admin inquiry log, the script executes, potentially leading to session hijacking or administrative actions.
2. Attack Vector Analysis
- Endpoint:
wp-admin/post.php(Product Edit Screen) or a custom AJAX action. - Payload Parameter: Likely a meta field such as
_enquiry_button_text,_enquiry_form_title, or_enquiry_custom_label. - Authentication: Contributor level or above. (Note: By default, Contributors cannot edit WooCommerce Products; however, if the plugin allows it or if the "Contributor" role was specifically granted
edit_productspermissions, the vulnerability triggers). - Precondition: WooCommerce must be active, and at least one product must exist that the attacker can modify or a shortcode they can use.
3. Code Flow (Inferred)
- Registration: The plugin uses
add_action( 'woocommerce_product_options_general_product_data', ... )to add inquiry settings to the product edit page. - Storage: The plugin uses
add_action( 'woocommerce_process_product_meta', 'save_inquiry_fields' ). - The Sink (Save): Inside the saving function,
update_post_meta( $post_id, 'some_meta_key', $_POST['some_meta_key'] )is called without sanitization. - The Source (Display): The plugin hooks into
woocommerce_single_product_summaryorwoocommerce_after_add_to_cart_button. - The Sink (Output): It retrieves the meta:
$text = get_post_meta( $post->ID, 'some_meta_key', true );and renders it:echo $text;(Unescaped).
4. Nonce Acquisition Strategy
If the plugin uses the standard WooCommerce product meta saving flow, the _wpnonce for post editing is required.
- Identify the Post ID: Locate a product ID (e.g.,
123). - Navigate to Edit Page: Use
browser_navigatetowp-admin/post.php?post=123&action=edit. - Extract Nonce:
// Extract the standard WordPress post nonce browser_eval("document.querySelector('#_wpnonce').value") - Plugin Specific Nonces: If the plugin uses a custom settings page or AJAX, search for
wp_localize_scriptin the source or HTML.- Check for a global object:
window.weic_varsor similar. - Example:
browser_eval("window.weic_vars?.nonce").
- Check for a global object:
5. Exploitation Strategy
Step 1: Identify Vulnerable Meta Fields
Scan the product edit page (or the plugin settings page) for input fields added by "Email Inquiry & Cart Options". Common labels: "Inquiry Button Text", "Inquiry Title".
Step 2: Inject Payload via POST Request
If a Contributor can edit products, send an editpost request.
- URL:
https://TARGET/wp-admin/post.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Parameters:
action:editpostpost_ID:123_wpnonce:[EXTRACTED_NONCE][VULNERABLE_FIELD]:<script>alert(document.domain)</script>- (Include other required fields like
post_titleto prevent errors)
Step 3: Trigger Execution
- Navigate to the public product page:
https://TARGET/?p=123. - The script should execute automatically if the inquiry button or text is rendered.
6. Test Data Setup
- Plugin Setup: Install WooCommerce and "Email Inquiry & Cart Options for WooCommerce".
- Role Adjustment: Ensure the test user has the "Contributor" role. If the plugin provides a specific dashboard for Contributors, use that. If not, elevate the Contributor to allow
edit_productsfor testing purposes as per the CVSS "Contributor+" context. - Content: Create a dummy product with ID
123. - Shortcode Page: Create a page
[email_inquiry_button]if the plugin uses shortcodes, as attributes in shortcodes are a common XSS vector for Contributors.
7. Expected Results
- Upon saving the product, the malicious string
<script>alert(document.domain)</script>is stored in thewp_postmetatable. - Upon viewing the product frontend, the browser executes the script, showing an alert box.
- The HTML source will show the payload rendered directly:
<span><script>alert(document.domain)</script></span>.
8. Verification Steps
- Database Check: Use WP-CLI to verify the unsanitized data is stored.
wp post meta get 123 [VULNERABLE_FIELD] - Frontend Check: Inspect the response headers and body using
http_requestto ensure the payload is present and not entity-encoded.# Look for raw script tags in the output grep "<script>alert"
9. Alternative Approaches
- Shortcode Attribute Injection: If the plugin provides a shortcode like
[email_inquiry], try:[email_inquiry button_text="<img src=x onerror=alert(1)>"]
Since Contributors can create posts/pages, this is a highly likely vector. - Settings Page XSS: If the plugin adds a settings menu accessible to Contributors (uncommon but possible), check for global settings fields.
- WooCommerce Tab Injection: Check if the plugin adds a custom tab to the WooCommerce product data meta box where labels can be customized.
Summary
The Email Inquiry & Cart Options for WooCommerce plugin fails to sanitize and escape custom product meta fields, such as inquiry button text and labels. This allows authenticated attackers with Contributor-level access or higher to inject malicious JavaScript into product pages, which then executes in the browser of any user viewing the affected product.
Vulnerable Code
// woocommerce-email-inquiry-cart-options/includes/admin/product-meta.php (inferred location) // Vulnerable saving of product meta without sanitization add_action( 'woocommerce_process_product_meta', 'weic_save_product_settings' ); function weic_save_product_settings( $post_id ) { if ( isset( $_POST['_enquiry_button_text'] ) ) { update_post_meta( $post_id, '_enquiry_button_text', $_POST['_enquiry_button_text'] ); } } --- // woocommerce-email-inquiry-cart-options/includes/public/display.php (inferred location) // Vulnerable output of product meta without escaping add_action( 'woocommerce_single_product_summary', 'weic_display_enquiry_button' ); function weic_display_enquiry_button() { global $post; $button_text = get_post_meta( $post->ID, '_enquiry_button_text', true ); if ( ! empty( $button_text ) ) { echo '<div class="weic-button-wrapper">' . $button_text . '</div>'; } }
Security Fix
@@ -3,1 +3,1 @@ -update_post_meta( $post_id, '_enquiry_button_text', $_POST['_enquiry_button_text'] ); +update_post_meta( $post_id, '_enquiry_button_text', sanitize_text_field( $_POST['_enquiry_button_text'] ) ); @@ -6,1 +6,1 @@ -echo '<div class="weic-button-wrapper">' . $button_text . '</div>'; +echo '<div class="weic-button-wrapper">' . esc_html( $button_text ) . '</div>';
Exploit Outline
1. Authenticate as a user with Contributor-level permissions (or any role capable of editing products/submitting meta). 2. Navigate to the WooCommerce product edit screen (wp-admin/post.php?post=[ID]&action=edit) or intercept a product update request. 3. Identify the meta fields registered by the plugin, specifically those related to 'Enquiry Button Text' or 'Inquiry Form Title'. 4. Inject a payload such as <script>alert(document.cookie)</script> into the target field. 5. Save the product, ensuring the standard WordPress post nonce (_wpnonce) is included in the request. 6. Visit the public-facing product page as any user. The browser will render the unsanitized meta value, executing the script in the user's session context.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.