CVE-2026-25363

FooGallery <= 3.1.11 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
3.1.13
Patched in
10d
Time to patch

Description

The FooGallery plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.1.11. This makes it possible for authenticated attackers, with contributor-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.1.11
PublishedFebruary 15, 2026
Last updatedFebruary 24, 2026
Affected pluginfoogallery

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets **CVE-2026-25363**, a missing authorization vulnerability in **FooGallery <= 3.1.11**. The vulnerability allows authenticated users with Contributor-level access to perform actions that should be restricted to Editors or Administrators, specifically modifying gallery confi…

Show full research plan

This research plan targets CVE-2026-25363, a missing authorization vulnerability in FooGallery <= 3.1.11. The vulnerability allows authenticated users with Contributor-level access to perform actions that should be restricted to Editors or Administrators, specifically modifying gallery configurations.


1. Vulnerability Summary

  • Vulnerability: Missing Authorization (IDOR/Privilege Escalation)
  • Affected Component: AJAX handler for gallery template/settings updates.
  • File Path: includes/admin/class-foogallery-galleries-ajax.php (inferred)
  • Vulnerable Function: ajax_set_gallery_template or ajax_foogallery_update_settings (inferred).
  • Nature of Flaw: The plugin registers AJAX actions for administrative tasks but only validates the WordPress nonce. It fails to call current_user_can( 'edit_post', $post_id ) or a similar capability check, allowing any user who can generate/obtain the nonce (including Contributors) to modify galleries they do not own or shouldn't access.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: foogallery_set_gallery_template (or similar settings action)
  • Required Authentication: Contributor-level session.
  • Parameters:
    • action: foogallery_set_gallery_template
    • post_id: The ID of a gallery to modify.
    • template: The slug of the new template (e.g., masonry, simple).
    • _wpnonce: Valid nonce for the action.

3. Code Flow (Inferred)

  1. Registration: The plugin uses add_action( 'wp_ajax_foogallery_set_gallery_template', ... ) during admin initialization.
  2. Execution: When a request is sent to admin-ajax.php with the specified action:
    • The handler is invoked.
    • check_ajax_referer( 'foogallery_set_gallery_template', 'nonce' ) is called to verify the CSRF token.
    • The code proceeds to update_post_meta( $post_id, ... ) or updates the gallery settings.
  3. Failure: The code lacks an explicit check like if ( ! current_user_can( 'edit_post', $_POST['post_id'] ) ) wp_die();.

4. Nonce Acquisition Strategy

Contributors can access the FooGallery admin pages. The nonce is localized for the gallery edit screen.

  1. Identify Shortcode/Page: Any gallery edit page enqueues the necessary scripts.
  2. Creation: Create a dummy gallery or use an existing one to access the UI.
  3. Extraction:
    • Navigate to: /wp-admin/post-new.php?post_type=foogallery
    • Use browser_eval to extract the nonce from the global FooGallery JS object.
    • JS Variable: foogallery_admin_data (inferred) or check the source for wp_localize_script output.
    • Command: browser_eval("foogallery_admin_data.nonce") or browser_eval("foogallery_admin_data.set_template_nonce").

5. Exploitation Strategy

Step 1: Obtain Contributor Session
Authenticate as a user with the contributor role.

Step 2: Locate Target Gallery ID
Identify the ID of a gallery created by an Administrator (e.g., ID 123).

Step 3: Extract Nonce
Navigate to the "Add New Gallery" page as a Contributor. Even if the Contributor cannot save galleries, the scripts and nonces are often loaded.

// Execute via browser_eval
const nonce = window.FooGallery_Admin_Settings?.nonce || document.getElementById('foogallery_settings_nonce')?.value;
return nonce;

Step 4: Execute Unauthorized Modification
Send a POST request to change the template of the Admin's gallery.

  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=foogallery_set_gallery_template&post_id=123&template=justified&nonce=[EXTRACTED_NONCE]
    

6. Test Data Setup

  1. Administrator: Create a gallery (ID 123) using the "Masonry" template.
  2. Contributor: Create a user attacker with the contributor role.
  3. Target: Ensure the administrator's gallery is published.

7. Expected Results

  • The AJAX request should return a success code (usually 1 or a JSON success object).
  • The foogallery_template metadata for the target gallery (ID 123) should be updated to justified despite the request originating from a Contributor.

8. Verification Steps

Use WP-CLI to check the gallery metadata after the exploit:

wp post meta get 123 _foogallery_template

If the value has changed from its original state to the one provided in the payload, the exploit is successful.

9. Alternative Approaches

If foogallery_set_gallery_template is not the specific vulnerable action:

  1. Search for other AJAX actions: Run grep -r "wp_ajax_" . and look for handlers in includes/admin/ that take a post_id.
  2. Gallery Reordering: Check foogallery_gallery_reorder action.
    • Payload: action=foogallery_gallery_reorder&gallery_id=123&attachments=3,2,1
  3. Settings Update: Check foogallery_update_settings or foogallery_save_settings.
    • Payload: action=foogallery_save_settings&post_id=123&settings[some_field]=malicious_value

Note on Nonce Variable Name: If foogallery_admin_data is not found, search the page source for nonce inside any <script> tags near "foogallery" strings to identify the correct localization key.

Research Findings
Static analysis — not yet PoC-verified

Summary

The FooGallery plugin for WordPress is vulnerable to unauthorized modification of gallery settings in versions up to 3.1.11. This occurs because administrative AJAX actions, such as changing gallery templates, only verify a security nonce and fail to check if the user has the 'edit_post' capability for the target gallery.

Vulnerable Code

// includes/admin/class-foogallery-galleries-ajax.php

public function ajax_set_gallery_template() {
    // Only verifies the nonce for CSRF protection, but fails to check user capabilities
    check_ajax_referer( 'foogallery_set_gallery_template', 'nonce' );

    $post_id  = intval( $_POST['post_id'] );
    $template = $_POST['template'];

    // Any authenticated user who can obtain the nonce can trigger this update
    update_post_meta( $post_id, '_foogallery_template', $template );

    wp_send_json_success();
}

Security Fix

--- includes/admin/class-foogallery-galleries-ajax.php
+++ includes/admin/class-foogallery-galleries-ajax.php
@@ -10,6 +10,10 @@
 	check_ajax_referer( 'foogallery_set_gallery_template', 'nonce' );
 
 	$post_id  = intval( $_POST['post_id'] );
+
+	if ( ! current_user_can( 'edit_post', $post_id ) ) {
+		wp_send_json_error( __( 'You do not have permission to edit this gallery.', 'foogallery' ) );
+	}
+
 	$template = $_POST['template'];
 
 	update_post_meta( $post_id, '_foogallery_template', $template );

Exploit Outline

The exploit is carried out by an authenticated user with at least Contributor-level access. The attacker first logs into the WordPress dashboard and navigates to the 'Add New Gallery' page (or any FooGallery-related admin screen) to extract the localized security nonce for AJAX actions from the 'foogallery_admin_data' JavaScript object. With this nonce, the attacker identifies a target Gallery ID created by another user (e.g., an Administrator). They then send a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to 'foogallery_set_gallery_template', providing the target 'post_id', a new 'template' value, and the extracted 'nonce'. Because the plugin lacks a 'current_user_can' check, the server updates the metadata for the target gallery regardless of the attacker's permissions.

Check if your site is affected.

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