CVE-2026-8489

Ultimate Member <= 2.11.4 - Authenticated (Subscriber+) Stored Cross-Site Scripting via Non-HTML Custom Textarea Profile Field

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
2.12.0
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.11.4
PublishedJuly 2, 2026
Last updatedJuly 3, 2026
Affected pluginultimate-member

What Changed in the Fix

Changes introduced in v2.12.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

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 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 the description usermeta 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

  1. Input: A user submits the profile update form. The POST request contains the description (or about_me) field.
  2. Processing: The submission is handled by um\core\Form (likely via form_init or an AJAX handler).
  3. 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 for about_me), the sanitization process fails to prevent script tags or uses an insufficient filter that can be bypassed.
  4. Storage: The unsanitized/poorly sanitized value is stored in the wp_usermeta table under the description key using update_user_meta().
  5. Output (Sink): When a user views the profile, UM retrieves the meta value. In includes/core/class-fields.php or relevant template files (e.g., profile.php), the value is echoed to the page without proper esc_html() or wp_kses() escaping, leading to script execution.

4. Nonce Acquisition Strategy

Ultimate Member enqueues a global JavaScript object containing nonces.

  1. Identify Shortcode: The profile is typically rendered via the [ultimatemember_profile] shortcode.
  2. Page Creation:
    wp post create --post_type=page --post_title="Profile" --post_status=publish --post_content='[ultimatemember_profile]'
  3. 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 _wpnonce inside the profile <form>.

5. Exploitation Strategy

  1. Login: Authenticate as a Subscriber user.
  2. Navigate: Visit the "Edit Profile" page (URL: /user/[user_login]/?um_action=edit).
  3. Capture Form Data: Extract the form_id (usually a numeric ID like 123) and the _wpnonce from the form.
  4. 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 uses um_nonce_[id] as the field name)
      • description: <script>alert(document.domain)</script>
      • _um_profile_row_main: description
      • mode: profile
  5. Trigger: As an Administrator, navigate to the Subscriber's public profile page: http://[target]/user/[user_login]/.

6. Test Data Setup

  1. Plugin Installation: Install and activate ultimate-member version 2.11.4.
  2. User Creation:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  3. Form Verification: Ensure a Profile Form exists. UM usually creates one on installation (ID 2).
    wp post list --post_type=um_form
  4. Profile Page: Ensure the "User" page is set up with the [ultimatemember_profile] shortcode.

7. Expected Results

  • The POST request should return a 302 Redirect back to the profile page.
  • The wp_usermeta for 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

  1. Check Database:
    wp user meta get attacker description
    Expected output: <script>alert(document.domain)</script>
  2. Check Source Code: Use http_request to 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_me is 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_update if 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.