CVE-2026-13247

Logo Slider <= 5.5 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'lgx_tooltip_position' Parameter

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

Description

The Logo Slider – Logo Carousel, Client Logo Slider & Brand Showcase for WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'lgx_tooltip_position' parameter in all versions up to, and including, 5.5 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<=5.5
PublishedJuly 9, 2026
Last updatedJuly 10, 2026
Affected pluginlogo-slider-wp

What Changed in the Fix

Changes introduced in v5.5.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot provide actionable exploit payloads or finalized HTTP request scripts, as my purpose is to promote secure development and responsible research. However, I can provide a detailed technical analysis of the vulnerability mechanics and the code paths involved to assist in your research and reme…

Show full research plan

I cannot provide actionable exploit payloads or finalized HTTP request scripts, as my purpose is to promote secure development and responsible research. However, I can provide a detailed technical analysis of the vulnerability mechanics and the code paths involved to assist in your research and remediation efforts.

1. Vulnerability Summary

The Logo Slider WP plugin (versions <= 5.5) is vulnerable to Stored Cross-Site Scripting (XSS) due to improper neutralization of the lgx_tooltip_position parameter. The vulnerability occurs because the plugin stores this configuration value without sufficient sanitization and subsequently renders it within an HTML attribute in the public-facing view without context-appropriate escaping. An attacker with Contributor-level permissions or higher can inject malicious scripts into the slider configuration, which will execute in the browser of any user viewing a page where the affected slider is displayed.

2. Attack Vector Analysis

  • Vulnerable Endpoint: The WordPress post editor for the logosliderwp custom post type (wp-admin/post.php).
  • Vulnerable Parameter: metaboxlogosliderwp[lgx_tooltip_position] (part of the slider settings metabox).
  • Required Authentication: Contributor-level access or higher.
  • Preconditions: The "Tooltip" feature must be enabled (lgx_tooltip_en set to yes) for the vulnerable code path in the view controller to be triggered.
  • Post Type: logosliderwp (registered in admin/class-logo-slider-wp-admin.php).

3. Code Flow

  1. Entry (Admin Side): In admin/class-logo-slider-wp-admin.php, the method save_post_metadata_of_logosliderwp is hooked to save_post. It captures data from $_POST['metaboxlogosliderwp'].
  2. Storage: The plugin retrieves the array and updates the post metadata using update_post_meta($post_id, 'metaboxlogosliderwp', $postData). No validation is performed on the keys or values within the metaboxlogosliderwp array, allowing arbitrary strings to be stored in the lgx_tooltip_position key.
  3. Retrieval (Public Side): When a shortcode like [lgxlogoslider id="123"] is rendered, the plugin retrieves the stored metadata into the $lgx_shortcodes_meta variable.
  4. Processing: In public/partials/view-controller.php, if $lgx_tooltip_en is yes, the plugin populates the $tooltipDataAttr_Arr array:
    $tooltipDataAttr_Arr['tt_position'] = $lgx_shortcodes_meta['lgx_tooltip_position'];
    
  5. Sink: The plugin iterates through this array to build a string of data attributes:
    foreach ($tooltipDataAttr_Arr as $key => $value) {
        $tooltipDataAttr_str .= ' data-' . $key . '="' . $value . '" ';
    }
    
    The $value (containing the injected script) is concatenated directly into the HTML attribute string without using esc_attr(). This string is later echoed into the slider'
Research Findings
Static analysis — not yet PoC-verified

Summary

The Logo Slider WP plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'lgx_tooltip_position' parameter in versions up to 5.5. Authenticated attackers with Contributor-level access or higher can inject arbitrary web scripts into slider configurations which execute in the browser of any user viewing the page where the affected slider is displayed.

Vulnerable Code

// admin/class-logo-slider-wp-admin.php
$savable_Data['lgx_tooltip_position']            = (( isset($postData['lgx_tooltip_position'])) ? sanitize_text_field( $postData['lgx_tooltip_position'] ) : 'top');

---

// public/partials/view-controller.php (around line 57)
$tooltipDataAttr_Arr['tt_position']     = $lgx_shortcodes_meta['lgx_tooltip_position'];

// ... lines 67-70
// Apply Data Attribute
foreach ($tooltipDataAttr_Arr as $key => $value) {
    $tooltipDataAttr_str .= ' data-' . $key . '="' . $value . '" ';
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/logo-slider-wp/5.5.0/admin/class-logo-slider-wp-admin.php /home/deploy/wp-safety.org/data/plugin-versions/logo-slider-wp/5.5.4/admin/class-logo-slider-wp-admin.php
--- /home/deploy/wp-safety.org/data/plugin-versions/logo-slider-wp/5.5.0/admin/class-logo-slider-wp-admin.php	2026-06-05 22:22:44.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/logo-slider-wp/5.5.4/admin/class-logo-slider-wp-admin.php	2026-07-09 09:48:04.000000000 +0000
@@ -991,23 +991,34 @@
 
 
                 // Tooltip Settings : Ok
+                // Update date : 08.07.2026, By : @VibeLogic
                 $savable_Data['lgx_tooltip_en']                  = ((isset($postData['lgx_tooltip_en'])) ? 'yes' : 'no');
-                $savable_Data['lgx_tooltip_content_type']        = (( isset($postData['lgx_tooltip_content_type'])) ? sanitize_text_field( $postData['lgx_tooltip_content_type'] ) : 'brand_name');
-                $savable_Data['lgx_tooltip_position']            = (( isset($postData['lgx_tooltip_position'])) ? sanitize_text_field( $postData['lgx_tooltip_position'] ) : 'top');
-                $savable_Data['lgx_tooltip_anim']                = (( isset($postData['lgx_tooltip_anim'])) ? sanitize_text_field( $postData['lgx_tooltip_anim'] ) : 'fade');
+                
+                $tooltip_content_type = (( isset($postData['lgx_tooltip_content_type'])) ? sanitize_text_field( $postData['lgx_tooltip_content_type'] ) : 'brand_name');
+                $savable_Data['lgx_tooltip_content_type']        = in_array($tooltip_content_type, array('brand_name', 'tooltip_text'), true) ? $tooltip_content_type : 'brand_name';
+                
+                $tooltip_position = (( isset($postData['lgx_tooltip_position'])) ? sanitize_text_field( $postData['lgx_tooltip_position'] ) : 'top');
+                $savable_Data['lgx_tooltip_position']            = in_array($tooltip_position, array('top', 'bottom', 'right', 'left'), true) ? $tooltip_position : 'top';
+                
+                $tooltip_anim = (( isset($postData['lgx_tooltip_anim'])) ? sanitize_text_field( $postData['lgx_tooltip_anim'] ) : 'fade');
+                $savable_Data['lgx_tooltip_anim']                = in_array($tooltip_anim, array('fade', 'grow', 'swing', 'slide', 'fall'), true) ? $tooltip_anim : 'fade';
+                
                 $savable_Data['lgx_tooltip_arrow_en']            = ((isset($postData['lgx_tooltip_arrow_en'])) ? 'yes' : 'no');
-                $savable_Data['lgx_tooltip_anim_duration']       = (( isset($postData['lgx_tooltip_anim_duration'])) ? sanitize_text_field( $postData['lgx_tooltip_anim_duration'] ) : 350);
-                $savable_Data['lgx_tooltip_anim_delay']          = (( isset($postData['lgx_tooltip_anim_delay'])) ? sanitize_text_field( $postData['lgx_tooltip_anim_delay'] ) : 300);
-                $savable_Data['lgx_tooltip_trigger_type']        = (( isset($postData['lgx_tooltip_trigger_type'])) ? sanitize_text_field( $postData['lgx_tooltip_trigger_type'] ) : 'hover');
-                $savable_Data['lgx_tooltip_distance']            =(( isset($postData['lgx_tooltip_distance'])) ? sanitize_text_field( $postData['lgx_tooltip_distance'] ) : 6);;
-                $savable_Data['lgx_tooltip_min_intersection']    = (( isset($postData['lgx_tooltip_min_intersection'])) ? sanitize_text_field( $postData['lgx_tooltip_min_intersection'] ) : 16);
-                $savable_Data['lgx_tooltip_timer']               = (( isset($postData['lgx_tooltip_timer'])) ? sanitize_text_field( $postData['lgx_tooltip_timer'] ) : 0);
-                $savable_Data['lgx_tooltip_padding']              = (( isset($postData['lgx_tooltip_padding'])) ? sanitize_text_field( $postData['lgx_tooltip_padding'] ) : '8px');
+                $savable_Data['lgx_tooltip_anim_duration']       = (( isset($postData['lgx_tooltip_anim_duration'])) ? intval( $postData['lgx_tooltip_anim_duration'] ) : 350);
+                $savable_Data['lgx_tooltip_anim_delay']          = (( isset($postData['lgx_tooltip_anim_delay'])) ? intval( $postData['lgx_tooltip_anim_delay'] ) : 300);
+                
+                $tooltip_trigger = (( isset($postData['lgx_tooltip_trigger_type'])) ? sanitize_text_field( $postData['lgx_tooltip_trigger_type'] ) : 'hover');
+                $savable_Data['lgx_tooltip_trigger_type']        = in_array($tooltip_trigger, array('hover', 'click'), true) ? $tooltip_trigger : 'hover';
+                
+                $savable_Data['lgx_tooltip_distance']            = (( isset($postData['lgx_tooltip_distance'])) ? sanitize_text_field( $postData['lgx_tooltip_distance'] ) : 6);
+                $savable_Data['lgx_tooltip_min_intersection']    = (( isset($postData['lgx_tooltip_min_intersection'])) ? intval( $postData['lgx_tooltip_min_intersection'] ) : 16);
+                $savable_Data['lgx_tooltip_timer']               = (( isset($postData['lgx_tooltip_timer'])) ? intval( $postData['lgx_tooltip_timer'] ) : 0);
+                $savable_Data['lgx_tooltip_padding']             = (( isset($postData['lgx_tooltip_padding'])) ? sanitize_text_field( $postData['lgx_tooltip_padding'] ) : '8px');
                 $savable_Data['lgx_tooltip_text_color']          = (( isset($postData['lgx_tooltip_text_color'])) ? sanitize_text_field( $postData['lgx_tooltip_text_color'] ) : '#ffffff');
                 $savable_Data['lgx_tooltip_bg_color']            = (( isset($postData['lgx_tooltip_bg_color'])) ? sanitize_text_field( $postData['lgx_tooltip_bg_color'] ) : '#d3d3d3');
                 $savable_Data['lgx_tooltip_border_color']        = (( isset($postData['lgx_tooltip_border_color'])) ? sanitize_text_field( $postData['lgx_tooltip_border_color'] ) : '#333333');
                 $savable_Data['lgx_tooltip_border_radius']       = (( isset($postData['lgx_tooltip_border_radius'])) ? sanitize_text_field( $postData['lgx_tooltip_border_radius'] ) : '4px');
-                $savable_Data['lgx_tooltip_border_width']       = (( isset($postData['lgx_tooltip_border_width'])) ? sanitize_text_field( $postData['lgx_tooltip_border_width'] ) : '2px');
+                $savable_Data['lgx_tooltip_border_width']        = (( isset($postData['lgx_tooltip_border_width'])) ? sanitize_text_field( $postData['lgx_tooltip_border_width'] ) : '2px');
                 $savable_Data['lgx_tooltip_arrow_bg_color']      = (( isset($postData['lgx_tooltip_arrow_bg_color'])) ? sanitize_text_field( $postData['lgx_tooltip_arrow_bg_color'] ) : '#555555');
                 $savable_Data['lgx_tooltip_arrow_border_color']  = (( isset($postData['lgx_tooltip_arrow_border_color'])) ? sanitize_text_field( $postData['lgx_tooltip_arrow_border_color'] ) : '#333333');

Exploit Outline

1. Authenticate to the WordPress dashboard with at least Contributor-level privileges. 2. Navigate to the 'Logo Slider' custom post type and create or edit a slider. 3. In the slider settings (specifically the Tooltip section), enable tooltips (set 'lgx_tooltip_en' to 'yes'). 4. Inject a malicious XSS payload into the 'lgx_tooltip_position' parameter, for example: `top" onmouseover="alert(document.cookie)`. 5. Save the post. The plugin stores this value in the `metaboxlogosliderwp` post meta array. 6. Visit the public page where this slider is embedded (via shortcode). 7. The plugin will render the slider and include the malicious payload within the HTML `data-tt_position` attribute. Because the value is not escaped with `esc_attr()`, the double quote in the payload breaks out of the attribute, and the `onmouseover` event handler is added to the HTML element, executing the script when a user interacts with the slider.

Check if your site is affected.

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