CVE-2025-15516

All-in-One Video Gallery 4.1.0 - 4.6.4 - Missing Authorization to Authenticated (Subscriber+) Limited User Meta Update

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

Description

The All-in-One Video Gallery plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the ajax_callback_store_user_meta() function in versions 4.1.0 to 4.6.4. This makes it possible for authenticated attackers, with Subscriber-level access and above, to update arbitrary string-based user meta keys for their own account.

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>=4.1.0 <=4.6.4
PublishedJanuary 23, 2026
Last updatedJanuary 24, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2025-15516 All-in-One Video Gallery User Meta Update ## 1. Vulnerability Summary The **All-in-One Video Gallery** plugin (versions 4.1.0 - 4.6.4) contains a missing authorization vulnerability in its AJAX handling logic. The function `ajax_callback_store_user_meta()` (inferred)…

Show full research plan

Research Plan: CVE-2025-15516 All-in-One Video Gallery User Meta Update

1. Vulnerability Summary

The All-in-One Video Gallery plugin (versions 4.1.0 - 4.6.4) contains a missing authorization vulnerability in its AJAX handling logic. The function ajax_callback_store_user_meta() (inferred) is registered to the wp_ajax_aiovg_store_user_meta action. This function fails to perform a capability check (e.g., current_user_can()) beyond verifying that the user is logged in. Consequently, any authenticated user with Subscriber-level permissions or higher can update arbitrary string-based user meta keys for their own account by sending a crafted AJAX request.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: aiovg_store_user_meta
  • HTTP Method: POST
  • Authentication: Required (Subscriber level or higher)
  • Vulnerable Parameters (inferred):
    • meta_key: The name of the user meta key to update (e.g., first_name, description).
    • meta_value: The value to set for the specified key.
    • _wpnonce or nonce: A security nonce usually required for WordPress AJAX actions.
  • Preconditions: The attacker must be logged in as a Subscriber.

3. Code Flow

  1. Entry Point: A logged-in user sends a POST request to admin-ajax.php with action=aiovg_store_user_meta.
  2. Hook Registration: The plugin registers the action (likely in includes/ajax.php or public/class-all-in-one-video-gallery-public.php):
    add_action( 'wp_ajax_aiovg_store_user_meta', array( $this, 'ajax_callback_store_user_meta' ) );
  3. Vulnerable Function: ajax_callback_store_user_meta() is called.
  4. Processing:
    • The function retrieves the meta_key and meta_value from the $_POST superglobal.
    • It likely verifies a nonce using check_ajax_referer( 'aiovg_ajax_nonce', 'nonce' ).
    • Critical Failure: It proceeds to call update_user_meta( get_current_user_id(), $meta_key, $meta_value ) without checking if the user is authorized to modify that specific meta key or if the operation is restricted to specific allowed keys.
  5. Sink: update_user_meta() modifies the wp_usermeta table in the database for the current user's ID.

4. Nonce Acquisition Strategy

The plugin localizes its AJAX data into a JavaScript object, typically aiovg_vars.

  1. Shortcode Identification: The plugin's scripts are usually enqueued on pages containing the [aiovg_video] or [aiovg_gallery] shortcodes.
  2. Page Creation: Use WP-CLI to create a public page containing the shortcode:
    wp post create --post_type=page --post_title="Video Gallery" --post_status=publish --post_content='[aiovg_video]'
    
  3. Browser Navigation: Use browser_navigate to visit the newly created page.
  4. Nonce Extraction: Use browser_eval to extract the nonce from the localized object. Based on common plugin patterns, the variable is likely aiovg_vars and the key is ajax_nonce.
    browser_eval("window.aiovg_vars?.ajax_nonce")
    

5. Exploitation Strategy

Step-by-Step Plan:

  1. Setup User: Create a Subscriber user and log in to obtain session cookies.
  2. Obtain Nonce: Create the gallery page, navigate to it, and extract the aiovg_vars.ajax_nonce using the strategy above.
  3. Forge Request: Use the http_request tool to send a POST request to modify a meta key. We will target the description (Biographical Info) field as a safe Proof-of-Concept.

Payload Details:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application-x-www-form-urlencoded
  • Body:
    action=aiovg_store_user_meta&nonce=[EXTRACTED_NONCE]&meta_key=description&meta_value=pwned_by_subscriber
    

6. Test Data Setup

  1. Plugin Installation: Ensure All-in-One Video Gallery v4.6.4 is active.
  2. Target User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
    
  3. Target Content:
    wp post create --post_type=page --post_title="Exploit Page" --post_status=publish --post_content='[aiovg_video]'
    

7. Expected Results

  • HTTP Response: The server should return a 200 OK or a JSON success message (e.g., {"success":true}).
  • Database Change: The description field for the attacker user in the wp_usermeta table should be updated to pwned_by_subscriber.

8. Verification Steps

After sending the HTTP request, verify the modification using WP-CLI:

wp user meta get attacker description

The output should be: pwned_by_subscriber.

9. Alternative Approaches

If the description key is protected by WordPress core filters, try updating a plugin-specific meta key or a generic one like first_name:

  • Payload 2: meta_key=first_name&meta_value=HackedName
  • Bypass Verification: If the nonce check fails, verify if the plugin registers wp_ajax_nopriv_aiovg_store_user_meta. If so, the attack can be performed unauthenticated.
  • Key Discovery: If meta_key is not the correct parameter name, check the JS source (likely assets/js/public.js) for the $.post call associated with aiovg_store_user_meta to find the exact key names used in the data object. (Likely keys: key, value, or meta_key, meta_value).
Research Findings
Static analysis — not yet PoC-verified

Summary

The All-in-One Video Gallery plugin fails to perform adequate authorization checks in its AJAX handler for user meta updates. This allows any authenticated user (Subscriber level or higher) to modify arbitrary string-based user meta fields for their own account, such as biographical information or custom plugin settings, by providing a valid nonce.

Vulnerable Code

// Likely located in public/class-all-in-one-video-gallery-public.php or similar AJAX handler file

public function ajax_callback_store_user_meta() {
    // Nonce verification exists, but lacks key-specific authorization or whitelisting
    check_ajax_referer( 'aiovg_ajax_nonce', 'nonce' );

    if ( is_user_logged_in() ) {
        $meta_key   = sanitize_text_field( $_POST['meta_key'] );
        $meta_value = sanitize_text_field( $_POST['meta_value'] );

        // Vulnerability: Updates ANY meta key for the current user without checking if the key is restricted
        update_user_meta( get_current_user_id(), $meta_key, $meta_value );
        wp_send_json_success();
    }

    wp_die();
}

Security Fix

--- a/public/class-all-in-one-video-gallery-public.php
+++ b/public/class-all-in-one-video-gallery-public.php
@@ -245,10 +245,13 @@
 	public function ajax_callback_store_user_meta() {
 		check_ajax_referer( 'aiovg_ajax_nonce', 'nonce' );
 
-		if ( is_user_logged_in() ) {
-			$meta_key   = sanitize_text_field( $_POST['meta_key'] );
-			$meta_value = sanitize_text_field( $_POST['meta_value'] );
+		if ( ! is_user_logged_in() ) {
+			wp_send_json_error();
+		}
 
+		$meta_key   = sanitize_text_field( $_POST['meta_key'] );
+		$meta_value = sanitize_text_field( $_POST['meta_value'] );
+
+		$allowed_keys = array( 'aiovg_player_volume', 'aiovg_player_muted' ); // Whitelisted specific keys
+		if ( in_array( $meta_key, $allowed_keys ) ) {
 			update_user_meta( get_current_user_id(), $meta_key, $meta_value );
 			wp_send_json_success();
 		}

+		wp_send_json_error();
 	}

Exploit Outline

1. Login as a Subscriber-level user to obtain session cookies. 2. Navigate to any page where the All-in-One Video Gallery is active (e.g., a page with the [aiovg_video] shortcode) to find the 'aiovg_ajax_nonce'. This is typically localized in the JavaScript object 'aiovg_vars.ajax_nonce'. 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'aiovg_store_user_meta'. 4. Include the 'nonce' parameter with the extracted nonce value. 5. Include a 'meta_key' parameter (e.g., 'description' for biographical info or 'first_name') and the desired 'meta_value'. 6. Verify the change by checking the user's profile metadata via the WordPress dashboard or WP-CLI.

Check if your site is affected.

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