Ultimate Member <= 2.11.4 - Authenticated (Subscriber+) Stored Cross-Site Scripting via Non-HTML Custom Textarea Profile Field
Description
The Ultimate Member – User Profile, Registration, Login, Member Directory, Content Restriction & Membership Plugin plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'about_me' parameter in all versions up to, and including, 2.11.4 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with subscriber-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
<=2.11.4What Changed in the Fix
Changes introduced in v2.12.0
Source Code
WordPress.org SVNThis research plan outlines the steps to verify the Stored Cross-Site Scripting (XSS) vulnerability in Ultimate Member (CVE-2026-8489). ### 1. Vulnerability Summary The **Ultimate Member** plugin is vulnerable to Stored XSS via the `about_me` (meta key `description`) parameter in user profile updat…
Show full research plan
This research plan outlines the steps to verify the Stored Cross-Site Scripting (XSS) vulnerability in Ultimate Member (CVE-2026-8489).
1. Vulnerability Summary
The Ultimate Member plugin is vulnerable to Stored XSS via the about_me (meta key description) parameter in user profile updates. While the plugin distinguishes between HTML-enabled and non-HTML textarea fields, it fails to sufficiently sanitize input or escape output for the "About Me" field when configured as a standard textarea. This allows an authenticated user (Subscriber+) to inject malicious scripts into their profile, which execute when viewed by other users, including administrators.
2. Attack Vector Analysis
- Vulnerable Parameter:
about_me(often mapped to thedescriptionusermeta key). - Endpoint: The User Profile update page (e.g.,
/user/[username]/?um_action=edit). - Authentication: Required (Subscriber-level or higher).
- Vulnerable Action: Profile submission via
POST. - Preconditions: The "About Me" field must be present in the Profile Form (default behavior).
3. Code Flow
- Input: A user submits the profile update form. The
POSTrequest contains thedescription(orabout_me) field. - Processing: The submission is handled by
um\core\Form(likely viaform_initor an AJAX handler). - Sanitization: The plugin identifies the field type as
textarea. In versions <= 2.11.4, if the field configuration has "Allow HTML" set to "No" (the default forabout_me), the sanitization process fails to prevent script tags or uses an insufficient filter that can be bypassed. - Storage: The unsanitized/poorly sanitized value is stored in the
wp_usermetatable under thedescriptionkey usingupdate_user_meta(). - Output (Sink): When a user views the profile, UM retrieves the meta value. In
includes/core/class-fields.phpor relevant template files (e.g.,profile.php), the value is echoed to the page without properesc_html()orwp_kses()escaping, leading to script execution.
4. Nonce Acquisition Strategy
Ultimate Member enqueues a global JavaScript object containing nonces.
- Identify Shortcode: The profile is typically rendered via the
[ultimatemember_profile]shortcode. - Page Creation:
wp post create --post_type=page --post_title="Profile" --post_status=publish --post_content='[ultimatemember_profile]' - Extraction: Navigate to the profile page as the logged-in Subscriber and use
browser_eval:- Variable Name:
um_scripts - Nonce Key:
nonce(The generic UM nonce). - Form Nonce: UM also embeds a hidden input field
_wpnonceinside the profile<form>.
- Variable Name:
5. Exploitation Strategy
- Login: Authenticate as a Subscriber user.
- Navigate: Visit the "Edit Profile" page (URL:
/user/[user_login]/?um_action=edit). - Capture Form Data: Extract the
form_id(usually a numeric ID like123) and the_wpnoncefrom the form. - Send Exploit Request:
- Tool:
http_request - Method:
POST - URL:
http://[target]/user/[user_login]/?um_action=edit - Headers:
Content-Type: application/x-www-form-urlencoded - Body Parameters:
form_id: [Extracted ID]um_nonce_[form_id]: [Extracted Nonce] (UM often usesum_nonce_[id]as the field name)description:<script>alert(document.domain)</script>_um_profile_row_main:descriptionmode:profile
- Tool:
- Trigger: As an Administrator, navigate to the Subscriber's public profile page:
http://[target]/user/[user_login]/.
6. Test Data Setup
- Plugin Installation: Install and activate
ultimate-memberversion 2.11.4. - User Creation:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password - Form Verification: Ensure a Profile Form exists. UM usually creates one on installation (ID 2).
wp post list --post_type=um_form - Profile Page: Ensure the "User" page is set up with the
[ultimatemember_profile]shortcode.
7. Expected Results
- The
POSTrequest should return a302 Redirectback to the profile page. - The
wp_usermetafor the attacker user will contain the literal<script>tag. - When visiting the profile page, an alert box showing the domain will appear in the browser, confirming the script executed.
8. Verification Steps
- Check Database:
wp user meta get attacker description
Expected output:<script>alert(document.domain)</script> - Check Source Code: Use
http_requestto GET the profile page and check if the payload is rendered raw:grep "<script>alert(document.domain)</script>" response_body.txt
9. Alternative Approaches
- Custom Textarea: If the default
about_meis patched or restricted, create a new custom field of type "Textarea" via the UM Form Builder (Admin dashboard), assign it a meta key (e.g.,my_custom_bio), and repeat the exploit. The vulnerability applies to "Non-HTML Custom Textarea" fields generally. - Payload Variation: If
<script>is blocked, use attribute-based XSS:"><img src=x onerror=alert(1)> - AJAX Endpoint: Check if the profile can be updated via the UM AJAX handler
um_profile_updateif the standard form submission is restricted.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.