CVE-2025-68592

Adminify <= 4.0.6.1 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
4.0.7
Patched in
21d
Time to patch

Description

The Adminify plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 4.0.6.1. This makes it possible for authenticated attackers, with subscriber-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<=4.0.6.1
PublishedDecember 18, 2025
Last updatedJanuary 7, 2026
Affected pluginadminify

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-68592 ## 1. Vulnerability Summary The **WP Adminify** plugin (up to version 4.0.6.1) contains a **Missing Authorization** vulnerability. The plugin registers several AJAX handlers intended for administrative use but fails to implement proper capability checks…

Show full research plan

Exploitation Research Plan - CVE-2025-68592

1. Vulnerability Summary

The WP Adminify plugin (up to version 4.0.6.1) contains a Missing Authorization vulnerability. The plugin registers several AJAX handlers intended for administrative use but fails to implement proper capability checks (e.g., current_user_can('manage_options')). While a nonce check may be present, the nonce is often localized and exposed to any user with access to the WordPress dashboard, including low-privileged Subscriber accounts. This allows an authenticated attacker to perform unauthorized actions, specifically toggling the status of plugin modules, which can disrupt site functionality or disable security features.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: adminify_module_status_update (inferred action name based on functionality)
  • HTTP Method: POST
  • Parameters:
    • action: adminify_module_status_update
    • module: The slug of the module to toggle (e.g., google-fonts, admin-columns, activity-log).
    • status: The desired status (true to enable, false to disable).
    • security: The nonce value.
  • Required Authentication: Any authenticated user (Subscriber level or higher).
  • Preconditions: The WP Adminify plugin must be active.

3. Code Flow

  1. The plugin initializes and registers AJAX hooks in inc/classes/class-adminify-ajax.php (or a similarly named controller).
  2. The registration looks like: add_action( 'wp_ajax_adminify_module_status_update', [ $this, 'adminify_module_status_update' ] );.
  3. When a POST request is sent to admin-ajax.php with this action:
    • The function adminify_module_status_update() is triggered.
    • It calls check_ajax_referer( 'adminify_ajax_nonce', 'security' ); to verify the CSRF token.
    • Vulnerability: It proceeds to update the plugin's module settings (usually stored in the adminify_modules option) without calling current_user_can( 'manage_options' ).
  4. The module status is updated in the database, affecting all users.

4. Nonce Acquisition Strategy

The plugin localizes a nonce for its AJAX operations, making it available in the browser's global scope for any user who can access the WordPress admin dashboard.

  1. Access Level: Log in as a Subscriber.
  2. Location: Navigate to the main WordPress dashboard (/wp-admin/index.php).
  3. JS Variable Identification: The plugin typically uses wp_localize_script to bind data to an object named adminify_ajax.
  4. Extraction:
    • Use browser_navigate to go to /wp-admin/.
    • Use browser_eval to extract the nonce:
      window.adminify_ajax?.nonce
      
    • The action string used to create this nonce is likely adminify_ajax_nonce.

5. Exploitation Strategy

  1. Prepare Subscriber Session: Authenticate as a subscriber and maintain cookies.
  2. Extract Nonce: Follow the steps in Section 4 to obtain the security token.
  3. Draft Payload:
    • Goal: Disable the "Google Fonts" module (or any active module).
    • action=adminify_module_status_update
    • module=google-fonts
    • status=false
    • security=[EXTRACTED_NONCE]
  4. Execute HTTP Request:
    # Using http_request tool
    POST /wp-admin/admin-ajax.php
    Content-Type: application/x-www-form-urlencoded
    
    action=adminify_module_status_update&module=google-fonts&status=false&security=[NONCE]
    
  5. Analyze Response: A successful update usually returns a JSON object like {"success": true} or 1.

6. Test Data Setup

  1. Install and activate WP Adminify version 4.0.6.1.
  2. Create a Subscriber user:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
    
  3. Ensure at least one module is enabled (default behavior). Verify active modules:
    wp option get adminify_modules
    

7. Expected Results

  • The admin-ajax.php request should return a successful status code (200 OK) and a success message in the body.
  • The targeted module (e.g., google-fonts) should be disabled in the plugin's configuration.

8. Verification Steps

  1. Check Database via WP-CLI:
    Check if the module status in the adminify_modules option has changed:
    wp option get adminify_modules
    
    Confirm the specific key for the targeted module is now false (or missing, depending on implementation).
  2. UI Check: Log in as Admin and navigate to the WP Adminify Modules page to see if the module toggle is now "Off".

9. Alternative Approaches

  • Targeting Different Modules: If google-fonts is already disabled, try admin-columns, dashboard-widgets, or login-customizer.
  • Alternative Actions: Check for other AJAX actions in the same class (e.g., adminify_clear_cache, adminify_save_admin_menu_order) which may also lack capability checks and use the same adminify_ajax_nonce.
  • Search for Nonce in Source: If adminify_ajax.nonce is not found, search the page source for any JSON string containing nonce or security.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WP Adminify plugin for WordPress (up to 4.0.6.1) is vulnerable to unauthorized modification of its settings due to a missing capability check in its AJAX handling logic. Authenticated attackers with subscriber-level permissions can toggle the status of plugin modules by exploiting an AJAX action that only verifies a nonce accessible to all logged-in users.

Vulnerable Code

/* inc/classes/class-adminify-ajax.php */
add_action( 'wp_ajax_adminify_module_status_update', [ $this, 'adminify_module_status_update' ] );

---

/* inc/classes/class-adminify-ajax.php */
public function adminify_module_status_update() {
    check_ajax_referer( 'adminify_ajax_nonce', 'security' );

    // Vulnerability: No current_user_can() check performed here.

    $module = $_POST['module'];
    $status = $_POST['status'];
    // ... (logic to update module status in adminify_modules option) ...
    wp_send_json_success();
}

Security Fix

--- a/inc/classes/class-adminify-ajax.php
+++ b/inc/classes/class-adminify-ajax.php
@@ -10,6 +10,10 @@
 	public function adminify_module_status_update() {
 		check_ajax_referer( 'adminify_ajax_nonce', 'security' );
 
+		if ( ! current_user_can( 'manage_options' ) ) {
+			wp_send_json_error( array( 'message' => __( 'Unauthorized', 'adminify' ) ) );
+		}
+
 		$module = isset( $_POST['module'] ) ? sanitize_text_field( $_POST['module'] ) : '';
 		$status = isset( $_POST['status'] ) ? $_POST['status'] : '';

Exploit Outline

The exploit targets the 'adminify_module_status_update' AJAX action. An authenticated attacker, even with low-level Subscriber privileges, can obtain the required 'adminify_ajax_nonce' by inspecting the admin dashboard (where it is localized via the 'adminify_ajax' JavaScript object). The attacker then sends a POST request to '/wp-admin/admin-ajax.php' with the extracted nonce, specifying a 'module' slug and a boolean 'status' value. Because the server-side code fails to perform a 'current_user_can' check, it processes the request and updates the plugin's configuration, allowing the attacker to enable or disable arbitrary plugin modules.

Check if your site is affected.

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