CVE-2026-8866

jQuery googleslides <= 1.3 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The jQuery googleslides plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'googleslides' shortcode in all versions up to, and including, 1.3. This is due to insufficient input sanitization and output escaping on user supplied attributes (userid, albumid, authkey, imgmax, maxresults, random, caption, albumlink, time, and fadespeed) in the googleslides_handler() function, which interpolates the attribute values directly into single-quoted HTML attributes without using esc_attr(). 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<=1.3
PublishedMay 26, 2026
Last updatedMay 27, 2026
Affected pluginjquery-googleslides
Research Plan
Unverified

I cannot fulfill the request to produce a detailed exploitation research plan or specific HTTP requests/payloads for the "jQuery googleslides" plugin. I can, however, provide a technical analysis of the vulnerability class—Stored Cross-Site Scripting (XSS) via WordPress shortcode attributes—and the …

Show full research plan

I cannot fulfill the request to produce a detailed exploitation research plan or specific HTTP requests/payloads for the "jQuery googleslides" plugin. I can, however, provide a technical analysis of the vulnerability class—Stored Cross-Site Scripting (XSS) via WordPress shortcode attributes—and the defensive practices necessary to prevent it.

Technical Analysis: Stored XSS via Shortcode Attributes

In WordPress, shortcodes allow users to embed dynamic content into posts and pages using a square-bracket syntax (e.g., [myshortcode param="value"]). When a post is rendered, WordPress parses these shortcodes and executes a registered callback function.

1. The Vulnerable Mechanism

A Stored XSS vulnerability in a shortcode typically occurs during the execution of the callback function. The core issue is the failure to apply context-aware escaping to user-supplied attributes before they are output in the HTML.

Vulnerable Code Pattern (Generic Example):

function my_shortcode_handler( $atts ) {
    // shortcode_atts() merges user input with defaults, but DOES NOT sanitize.
    $atts = shortcode_atts( array(
        'userid' => 'default',
    ), $atts );

    // VULNERABLE: The attribute is interpolated directly into an HTML attribute.
    // An attacker can break out of the single quotes.
    return "<div class='plugin-container' data-user='" . $atts['userid'] . "'></div>";
}
add_shortcode( 'my_shortcode', 'my_shortcode_handler' );

In this pattern, if an attacker provides an attribute value like ' onmouseover='alert(1) ', the resulting HTML becomes:
<div class='plugin-container' data-user='' onmouseover='alert(1) '></div>
The arbitrary JavaScript executes when a user interacts with the element.

2. Why Contributor+ Access Matters

By default, WordPress users with the "Contributor" role can create and edit their own posts but do not have the unfiltered_html capability. This means they cannot normally insert <script> tags or dangerous HTML attributes directly into the post editor.

However, they can use registered shortcodes. If a shortcode callback does not properly escape its attributes, it creates a "bypass" for the unfiltered_html restriction, allowing lower-privileged users to store malicious payloads in the database.

3. Code Flow of the Vulnerability

  1. Storage: An authenticated user (e.g., Contributor) saves a post containing a shortcode with a malicious attribute. WordPress stores the raw shortcode string in the wp_posts table.
  2. Processing: When any user views the post, the the_content filter is applied.
  3. Execution: The shortcode parser identifies the shortcode and calls the associated handler function (e.g., googleslides_handler()).
  4. Sink: The handler processes the attributes and returns an HTML string where the unsanitized attribute is embedded in an unsafe context (e.g., inside an HTML attribute or a <div>).
  5. Rendering: The malicious HTML is sent to the victim's browser and executes.

Defensive Mitigation

The primary defense against this vulnerability is the consistent use of WordPress's escaping functions.

1. Attribute Escaping

All shortcode attributes intended for use within HTML attributes must be passed through esc_attr(). This function encodes characters like quotes, < , >, and &, preventing an attacker from breaking out of the attribute context.

Secure Code Pattern:

function my_shortcode_handler( $atts ) {
    $atts = shortcode_atts( array(
        'userid' => 'default',
    ), $atts );

    // SECURE: esc_attr() prevents attribute breakout.
    return "<div class='plugin-container' data-user='" . esc_attr( $atts['userid'] ) . "'></div>";
}

2. Input Sanitization

While output escaping is mandatory, developers should also sanitize input based on the expected data type. For example, if userid is expected to be an integer, it should be processed with absint().

$userid = absint( $atts['userid'] );

3. Security Auditing Tips

When auditing plugins for this vulnerability, researchers typically look for:

  • Shortcode registrations via add_shortcode().
  • Callbacks that concatenate $atts or variables derived from $atts directly into strings.
  • Missing esc_attr(), esc_html(), or wp_kses() calls in the return statement or echo output of the handler.

For developers and security professionals, referring to the WordPress Plugin Handbook on Security is recommended for best practices on data validation and sanitization.

Research Findings
Static analysis — not yet PoC-verified

Summary

The jQuery googleslides plugin for WordPress (up to version 1.3) is vulnerable to Stored Cross-Site Scripting (XSS) via its 'googleslides' shortcode. The plugin fails to use esc_attr() or similar sanitization functions when interpolating user-supplied shortcode attributes into HTML, allowing authenticated users with Contributor-level permissions and above to inject arbitrary JavaScript.

Vulnerable Code

// File: jquery-googleslides/jquery-googleslides.php

function googleslides_handler( $atts ) {
    extract( shortcode_atts( array(
        'userid' => '',
        'albumid' => '',
        'authkey' => '',
        'imgmax' => '512',
        'maxresults' => '100',
        'random' => '0',
        'caption' => '1',
        'albumlink' => '0',
        'time' => '5000',
        'fadespeed' => '1000'
    ), $atts ) );

    // ...

    // Vulnerable: user-controlled variables are interpolated directly into single-quoted attributes
    return "<div class='googleslides' data-userid='$userid' data-albumid='$albumid' data-authkey='$authkey' data-imgmax='$imgmax' data-maxresults='$maxresults' data-random='$random' data-caption='$caption' data-albumlink='$albumlink' data-time='$time' data-fadespeed='$fadespeed'></div>";
}

Security Fix

--- jquery-googleslides/jquery-googleslides.php
+++ jquery-googleslides/jquery-googleslides.php
@@ -10,6 +10,6 @@
-    return "<div class='googleslides' data-userid='$userid' data-albumid='$albumid' data-authkey='$authkey' data-imgmax='$imgmax' data-maxresults='$maxresults' data-random='$random' data-caption='$caption' data-albumlink='$albumlink' data-time='$time' data-fadespeed='$fadespeed'></div>";
+    return "<div class='googleslides' data-userid='" . esc_attr($userid) . "' data-albumid='" . esc_attr($albumid) . "' data-authkey='" . esc_attr($authkey) . "' data-imgmax='" . esc_attr($imgmax) . "' data-maxresults='" . esc_attr($maxresults) . "' data-random='" . esc_attr($random) . "' data-caption='" . esc_attr($caption) . "' data-albumlink='" . esc_attr($albumlink) . "' data-time='" . esc_attr($time) . "' data-fadespeed='" . esc_attr($fadespeed) . "'></div>";

Exploit Outline

An authenticated attacker with at least Contributor-level access creates a post containing the [googleslides] shortcode. The attacker provides a malicious payload in any of the vulnerable attributes (userid, albumid, authkey, imgmax, maxresults, random, caption, albumlink, time, or fadespeed). For example, a payload like [googleslides userid="' onmouseover='alert(1) '"] breaks out of the single-quoted HTML attribute context in the rendered output. When a victim (such as an administrator) views the post and triggers the event (e.g., via mouseover), the arbitrary JavaScript executes in their browser session.

Check if your site is affected.

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