CVE-2025-12081

ACF Photo Gallery Field <= 3.0 - Missing Authorization to Authenticated (Subscriber+) Attachment Metadata Modification

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
3.1
Patched in
1d
Time to patch

Description

The ACF Photo Gallery Field plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the "acf_photo_gallery_edit_save" function in all versions up to, and including, 3.0. This makes it possible for authenticated attackers, with subscriber level access and above, to modify the title, caption, and custom metadata of arbitrary media attachments.

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.0
PublishedFebruary 18, 2026
Last updatedFebruary 19, 2026
Affected pluginnavz-photo-gallery

Source Code

WordPress.org SVN
Research Plan
Unverified

This plan outlines the research and exploitation steps for CVE-2025-12081, a missing authorization vulnerability in the **ACF Photo Gallery Field** plugin. --- ### 1. Vulnerability Summary **ID:** CVE-2025-12081 **Plugin:** ACF Photo Gallery Field (`navz-photo-gallery`) **Affected Versions:** …

Show full research plan

This plan outlines the research and exploitation steps for CVE-2025-12081, a missing authorization vulnerability in the ACF Photo Gallery Field plugin.


1. Vulnerability Summary

ID: CVE-2025-12081
Plugin: ACF Photo Gallery Field (navz-photo-gallery)
Affected Versions: <= 3.0
Vulnerability Type: Missing Authorization
CVSS: 4.3 (Medium)
Vulnerable Function: acf_photo_gallery_edit_save

The vulnerability exists because the function acf_photo_gallery_edit_save, which is hooked to the wp_ajax_acf_photo_gallery_edit_save action, lacks a capability check (e.g., current_user_can()). While it may verify a nonce, that nonce is typically available to any authenticated user who can access an admin page or a page where the ACF gallery field is rendered. This allows a Subscriber-level user to modify the title, caption, and metadata of any WordPress media attachment by specifying its ID.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Method: POST
  • Action: acf_photo_gallery_edit_save
  • Authentication Required: Subscriber-level (authenticated)
  • Vulnerable Parameters:
    • id: The ID of the target attachment to modify.
    • title: The new title for the attachment.
    • caption: The new caption.
    • alt: The new Alt text.
    • description: The new description.
  • Preconditions: The attacker must be logged in as at least a Subscriber and have a valid AJAX nonce.

3. Code Flow (Inferred)

  1. Entry Point: WordPress receives a POST request to admin-ajax.php with action=acf_photo_gallery_edit_save.
  2. Hook Execution: WordPress triggers the action wp_ajax_acf_photo_gallery_edit_save.
  3. Handler Function: The function acf_photo_gallery_edit_save() is called.
  4. Nonce Verification: The function likely calls check_ajax_referer( 'acf_photo_gallery_nonce', 'nonce' ) or similar.
  5. Missing Auth Check: The function proceeds to update the attachment without checking if the current user has the edit_posts or edit_others_posts capability.
  6. Data Sink: The function uses wp_update_post() for the title/caption and update_post_meta() for the alt text and description, targeting the user-supplied id.

4. Nonce Acquisition Strategy

The plugin likely enqueues a script that localizes the nonce for the gallery editing modal.

  1. Identify Script Localization: The plugin likely uses wp_localize_script() in its main file or an admin-related include.
    • Possible JS Object: acf_photo_gallery_js_obj (inferred from plugin name)
    • Possible Nonce Key: nonce or acf_photo_gallery_nonce
  2. Determine Page Source: The nonce is likely available on any page where the ACF field is active in the editor. However, if the plugin enqueues the script globally in the admin area, any Subscriber can find it on /wp-admin/profile.php.
  3. Extraction Steps:
    • Log in as a Subscriber.
    • Navigate to /wp-admin/profile.php.
    • Use browser_eval to search for the nonce:
      // Example search for the nonce object
      window.acf_photo_gallery_js_obj?.nonce || 
      window.navz_gallery_obj?.nonce
      
    • If not found on the profile page, check if the nonce is exposed on the frontend where a gallery is displayed.

5. Test Data Setup

  1. Install Plugin: Install and activate navz-photo-gallery version 3.0.
  2. Target Media: As an Administrator, upload an image to the Media Library. Note its ID (e.g., 123).
    • Set initial values: Title="Original Title", Caption="Original Caption".
  3. Attacker User: Create a user with the Subscriber role.
  4. ACF Field (Optional): You may need to create an ACF Field Group with a "Photo Gallery" field and assign it to "Posts" to ensure the plugin's scripts load.

6. Exploitation Strategy

Once the Subscriber user is created and the target Attachment ID is known:

Step 1: Extract the Nonce

  • Log in as the Subscriber.
  • Navigate to the WordPress dashboard (/wp-admin/).
  • Execute browser_eval to find the nonce variable.
    • Note: Check the page source for wp_localize_script output to find the exact variable name.

Step 2: Execute the Modification

  • Use http_request to send the payload.

Payload Request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=acf_photo_gallery_edit_save&nonce=[EXTRACTED_NONCE]&id=[TARGET_ATTACHMENT_ID]&title=Vulnerable+Title&caption=Vulnerable+Caption&alt=Vulnerable+Alt&description=Vulnerable+Desc

7. Expected Results

  • Response: The server should return a successful status (usually 1 or a JSON success message like {"success":true}).
  • Effect: The media attachment with the specified ID will have its title changed to "Vulnerable Title" and caption changed to "Vulnerable Caption", regardless of who owns the attachment.

8. Verification Steps

  1. WP-CLI Check:
    wp post get [TARGET_ATTACHMENT_ID] --field=post_title
    wp post get [TARGET_ATTACHMENT_ID] --field=post_excerpt # This is the caption
    wp post_meta get [TARGET_ATTACHMENT_ID] _wp_attachment_image_alt
    
  2. Success Criteria: The output of these commands should match the "Vulnerable" strings sent in the payload.

9. Alternative Approaches

  • LFI/Unserialize Check: If the metadata modification allows updating arbitrary meta keys, check if _wp_attached_file can be modified (Path Traversal/LFI risk) or if other sensitive meta can be overwritten.
  • Frontend Check: If the Subscriber cannot access /wp-admin/, check if the plugin exposes the nonce on the frontend for users who can view posts containing the gallery field.
  • Action Guessing: If the exact nonce action name is unknown, search the plugin source code for wp_create_nonce or check_ajax_referer. (e.g., grep -r "check_ajax_referer" .)
Research Findings
Static analysis — not yet PoC-verified

Summary

The ACF Photo Gallery Field plugin for WordPress lacks authorization checks in its AJAX handler for saving attachment metadata. Authenticated users with Subscriber-level permissions or higher can modify the title, caption, description, and alternative text of any media attachment by providing a valid nonce and the target attachment ID.

Vulnerable Code

// Likely located in the main plugin file or an admin handler

add_action( 'wp_ajax_acf_photo_gallery_edit_save', 'acf_photo_gallery_edit_save' );

function acf_photo_gallery_edit_save() {
    // Nonce check exists, but any authenticated user can typically access this nonce
    check_ajax_referer( 'acf_photo_gallery_nonce', 'nonce' );

    // Missing capability check (e.g., current_user_can( 'edit_posts' ))

    $id = intval( $_POST['id'] );
    $post = array(
        'ID'           => $id,
        'post_title'   => sanitize_text_field( $_POST['title'] ),
        'post_excerpt' => sanitize_text_field( $_POST['caption'] ),
        'post_content' => sanitize_textarea_field( $_POST['description'] ),
    );

    wp_update_post( $post );
    update_post_meta( $id, '_wp_attachment_image_alt', sanitize_text_field( $_POST['alt'] ) );

    wp_send_json_success();
}

Security Fix

--- navz-photo-gallery.php
+++ navz-photo-gallery.php
@@ -100,6 +100,10 @@
 function acf_photo_gallery_edit_save() {
     check_ajax_referer( 'acf_photo_gallery_nonce', 'nonce' );
 
+    if ( ! current_user_can( 'edit_posts' ) ) {
+        wp_send_json_error( array( 'message' => 'Permission denied' ), 403 );
+    }
+
     $id = intval( $_POST['id'] );
     $post = array(
         'ID'           => $id,

Exploit Outline

To exploit this vulnerability, an attacker must first obtain a valid Subscriber-level account on the WordPress site. By navigating to an admin page (like /wp-admin/profile.php) or a frontend page where the ACF Photo Gallery script is localized, the attacker extracts the 'acf_photo_gallery_nonce' from the localized JavaScript object (e.g., window.acf_photo_gallery_js_obj). The attacker then sends a POST request to /wp-admin/admin-ajax.php with the action parameter 'acf_photo_gallery_edit_save', the extracted nonce, and the target attachment's ID. The payload includes new values for 'title', 'caption', 'alt', and 'description', which the plugin will apply to the specified media attachment without verifying if the user has permission to edit that post or media.

Check if your site is affected.

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