UiChemy <= 4.4.2 - Authenticated (Author+) Stored Cross-Site Scripting
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:NTechnical Details
Source Code
WordPress.org SVN# 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.phpor the WordPress REST API (Gutenberg block attributes). - Action:
uichemy_save_design(inferred) or viawp-json/wp/v2/posts/. - Vulnerable Parameter:
design_data,content, or specific block attributes likefigma_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
- Entry Point: The user interacts with the UiChemy interface within the WordPress post editor (Gutenberg/Elementor).
- 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). - Processing: The PHP handler (e.g.,
UiChemy\Classes\Ajax_Handler::save_design) receives the JSON payload. - 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). - Rendering (Sink): When the post is viewed, the plugin retrieves this metadata and outputs it. If the output is handled via a
render_callbackfor a block or a shortcode, and it usesechoinstead 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.
- Identify Script: Look for the localization script for UiChemy, likely named
uichemy-admin-jsoruichemy-editor. - Create Page: Authors can create pages.
wp post create --post_type=page --post_status=publish --post_title="XSS Probe" --post_author=[AUTHOR_ID] - Navigate & Extract: Use the
browser_navigatetool to open the editor for this page. - Extract Nonce:
// Inferred localization keys - common in UiChemy browser_eval("window.uichemy_vars?.nonce || window.uichemy_obj?.ajax_nonce") - 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:
(Note:{ "content": "<!-- wp:uichemy/figma-import {\"htmlData\": \"<img src=x onerror=alert(document.domain)>\"} /-->" }uichemy/figma-importandhtmlDataare 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
- User: Create an Author user.
wp user create attacker attacker@example.com --role=author --user_pass=password123 - 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 - 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 OKor201 Createdresponse. - When navigating to the published post URL or viewing the post in the editor as an Admin, an alert box with
document.domainshould appear. - The malicious payload should be visible in the page source within the UiChemy container, unescaped.
8. Verification Steps
- 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]" - HTML Inspection: Use
http_requestto 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_requesttool to send awp_ajax_elementor_ajaxrequest with theuichemywidget's settings modified to include the XSS payload. - Figma Token Leakage: If the XSS is successful, use a payload to exfiltrate the
uichemy_figma_tokenoption from the WordPress database, which would allow the attacker to access the victim's Figma designs. - CSS Injection: If
<script>andonerrorare filtered, try injecting XSS via CSS properties:{"style": "background-image: url('javascript:alert(1)')"}.
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
@@ -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 ); @@ -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.