CVE-2026-24389

Gallery PhotoBlocks <= 1.3.2 - Authenticated (Contributor+) Stored Cross-Site Scripting

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

Description

The Gallery PhotoBlocks plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.3.2 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: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.2
PublishedJanuary 26, 2026
Last updatedFebruary 2, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

Based on the vulnerability details and the WordPress security knowledge base provided, here is a detailed exploitation research plan for **CVE-2026-24389: Gallery PhotoBlocks <= 1.3.2 - Authenticated (Contributor+) Stored Cross-Site Scripting**. --- ### 1. Vulnerability Summary **Gallery PhotoBloc…

Show full research plan

Based on the vulnerability details and the WordPress security knowledge base provided, here is a detailed exploitation research plan for CVE-2026-24389: Gallery PhotoBlocks <= 1.3.2 - Authenticated (Contributor+) Stored Cross-Site Scripting.


1. Vulnerability Summary

Gallery PhotoBlocks is a grid gallery plugin that allows users to create and manage visual galleries. In versions up to 1.3.2, the plugin fails to sufficiently sanitize or escape user-provided data when saving gallery configurations or block attributes. This allows a user with Contributor permissions or higher to inject malicious scripts (Stored XSS) into the gallery data. These scripts execute in the context of any user (including Administrators) who views the gallery on the frontend or manages it in the backend.

2. Attack Vector Analysis

  • Endpoint: WordPress AJAX API (/wp-admin/admin-ajax.php).
  • Action: photoblocks_save or pb_save_gallery (inferred from plugin slug and common patterns).
  • Parameter: Typically a JSON-encoded string or an array of block settings (e.g., data, gallery_data, or blocks).
  • Vulnerable Fields: Likely fields include block titles, descriptions, custom CSS areas, or link URL attributes that are later rendered in the gallery grid.
  • Authentication: Authenticated (Contributor+). Contributor is sufficient as they generally have permissions to create or edit galleries/posts depending on plugin configuration.
  • Preconditions: The plugin must be active. The attacker needs a valid session and a WordPress nonce for the specific AJAX action.

3. Code Flow (Inferred)

  1. Entry Point: The user triggers an AJAX request to save a gallery.
  2. Handler: The plugin registers an AJAX handler via add_action('wp_ajax_photoblocks_save', ...).
  3. Data Processing: The handler retrieves the gallery configuration from $_POST.
  4. Insecure Sink (Storage): The data is saved to the database (likely in wp_postmeta under a key like _photoblocks_data) using update_post_meta() without rigorous sanitization (e.g., using wp_kses or sanitize_text_field on every sub-attribute).
  5. Insecure Sink (Output): When the gallery is rendered via the [photoblocks] shortcode or in the admin preview, the plugin echoes the stored attributes without context-appropriate escaping (e.g., esc_attr() or esc_html()).

4. Nonce Acquisition Strategy

To exploit the AJAX endpoint, a valid nonce is required. Since we are testing as a Contributor, we can navigate to the gallery editor page to find it.

  1. Identify the Script: The plugin likely localizes data using wp_localize_script.
  2. Navigate to Admin: Use browser_navigate to go to the PhotoBlocks gallery list or editor: /wp-admin/admin.php?page=photoblocks-galleries (inferred).
  3. Extract Nonce: Use browser_eval to extract the nonce from the global JavaScript object.
    • Inferred Variable Name: window.photoblocks_obj?.nonce or window.pb_config?.nonce.
    • Action: browser_eval("window.pb_config.nonce") (replace pb_config with the actual localized variable found in the page source).

5. Exploitation Strategy

The plan involves injecting a script into a gallery attribute that will be rendered when the gallery is viewed.

Step 1: Create a Gallery (if none exists)
As a Contributor, create a new PhotoBlock gallery to obtain a gallery_id.

Step 2: Intercept/Identify the Save Request
Determine the exact structure of the save request by observing the "Save" action in the gallery editor.

  • Payload Example (JSON):
    {
      "blocks": [
        {
          "title": "Gallery Block <img src=x onerror=alert(document.domain)>",
          "description": "Exploit"
        }
      ]
    }
    

Step 3: Send Malicious HTTP Request
Using the http_request tool, send a POST request to admin-ajax.php.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=pb_save_gallery&nonce=[NONCE]&id=[GALLERY_ID]&data=[URL_ENCODED_JSON_PAYLOAD]
    
    (Note: Replace pb_save_gallery and data with the actual parameter names discovered).

Step 4: Trigger XSS
Place the gallery shortcode on a public page and view it as an Administrator.

  • Shortcode: [photoblocks id="[GALLERY_ID]"]

6. Test Data Setup

  1. User: Create a user with the Contributor role.
  2. Post: Create a new page/post to host the gallery shortcode:
    wp post create --post_type=page --post_status=publish --post_title="Gallery Test" --post_content='[photoblocks id="1"]' (adjust ID as necessary).

7. Expected Results

  • The AJAX request should return a success response (e.g., {"success": true}).
  • When navigating to the "Gallery Test" page as an Admin, an alert box showing the document domain should appear.
  • In the HTML source of the rendered gallery, the payload <img src=x onerror=alert(document.domain)> should appear unescaped within an attribute or tag.

8. Verification Steps

  1. Check Database: Verify the payload is stored in the postmeta table.
    wp db query "SELECT meta_value FROM wp_postmeta WHERE meta_key = '_photoblocks_data' AND post_id = [GALLERY_ID]"
    
  2. Verify Frontend Execution:
    Use browser_navigate to the page containing the shortcode and check for the alert or the presence of the injected string in the DOM.

9. Alternative Approaches

  • Custom CSS Sink: If the plugin allows "Custom CSS" per gallery, inject: }</style><script>alert(1)</script>.
  • Image Metadata: If the plugin pulls titles from the Media Library, try injecting XSS into the image "Title" or "Caption" fields in the Media Library, then adding that image to a PhotoBlock.
  • Settings API: Check if the plugin has global settings accessible to Contributors (unlikely, but worth checking register_setting calls).

Technical Identifiers (Inferred - To be verified by agent)

  • AJAX Actions: pb_save_gallery, pb_get_gallery, photoblocks_save.
  • JS Localized Key: pb_config, photoblocks_admin.
  • Post Meta Key: _photoblocks_data, _pb_settings.
  • Shortcode: [photoblocks], [photoblock].
Research Findings
Static analysis — not yet PoC-verified

Summary

The Gallery PhotoBlocks plugin for WordPress is vulnerable to Stored Cross-Site Scripting due to insufficient input sanitization and output escaping of gallery block attributes. Authenticated attackers with Contributor-level permissions or higher can inject malicious JavaScript into gallery settings via AJAX, which executes when the gallery is rendered for visitors or administrators.

Exploit Outline

1. Authenticate as a Contributor-level user and navigate to the PhotoBlocks gallery management interface to extract the localized security nonce (likely found in a global JS object like `pb_config.nonce`). 2. Identify the gallery ID of an existing gallery or create a new one. 3. Prepare a malicious JSON payload for the gallery configuration where block attributes (e.g., 'title' or 'description') contain an XSS payload such as `<img src=x onerror=alert(document.domain)>`. 4. Send an authenticated POST request to `/wp-admin/admin-ajax.php` with the `action` set to `pb_save_gallery`, the acquired `nonce`, the `id` of the gallery, and the malicious payload in the `data` parameter. 5. Embed the gallery shortcode `[photoblocks id="GALLERY_ID"]` into a post or page. 6. The script will execute whenever an Administrator or any other user views the affected page.

Check if your site is affected.

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