CVE-2026-39690

Author Avatars List/Block <= 2.1.25 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Author Avatars List/Block plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.1.25. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.1.25
PublishedFebruary 23, 2026
Last updatedApril 15, 2026
Affected pluginauthor-avatars
Research Plan
Unverified

This research plan focuses on identifying and exploiting a **Missing Authorization** vulnerability in the **Author Avatars List/Block** plugin (version <= 2.1.25). Based on the CVSS vector (**CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N**), the vulnerability allows an unauthenticated attacker to m…

Show full research plan

This research plan focuses on identifying and exploiting a Missing Authorization vulnerability in the Author Avatars List/Block plugin (version <= 2.1.25).

Based on the CVSS vector (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N), the vulnerability allows an unauthenticated attacker to modify data (Integrity: Low) but not necessarily read sensitive information (Confidentiality: None). This typically points to an unauthorized AJAX action or an admin_init hook that allows dismissing notices, clearing caches, or updating minor plugin settings.


1. Vulnerability Summary

The "Author Avatars List/Block" plugin fails to implement proper capability checks (e.g., current_user_can()) on one or more AJAX handlers registered via wp_ajax_nopriv_*. This allows any unauthenticated user to trigger functions intended for administrators. In this specific version range, the candidate for "Integrity: Low" impact is the unauthorized dismissal of administrative notices or modification of plugin-specific transients/options.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: aa_dismiss_notice (inferred) or a similar aa_* prefixed action.
  • Parameter: notice_id or id.
  • Authentication: None (Unauthenticated).
  • Preconditions: The plugin must be active. For some actions, a specific notice or state must exist to be "modified."

3. Code Flow

  1. Registration: The plugin registers an AJAX action in lib/AuthorAvatars.class.php (or a similar admin/notices class) using:
    add_action( 'wp_ajax_nopriv_aa_dismiss_notice', array( $this, 'ajax_dismiss_notice' ) );
  2. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with action=aa_dismiss_notice.
  3. Missing Check: The ajax_dismiss_notice function executes without calling current_user_can( 'manage_options' ).
  4. Sink: The function calls update_option() or set_transient() to mark the notice as dismissed, modifying the site's state.

4. Nonce Acquisition Strategy

If the handler requires a nonce (common in check_ajax_referer), we must locate where the plugin localizes this nonce for unauthenticated users.

  1. Identify the Script: Look for wp_localize_script in the codebase.
    • Command: grep -r "wp_localize_script" .
  2. Locate the Key: Identify the object name and key (e.g., window.author_avatars_settings?.nonce).
  3. Setup Page: Create a page containing the plugin's shortcode to ensure the script (and nonce) is loaded.
    • wp post create --post_type=page --post_status=publish --post_content='[author_avatars]'
  4. Extract: Use the browser to navigate to the new page and extract the nonce.
    • browser_navigate(URL)
    • NONCE = browser_eval("window.aa_ajax_object?.nonce") (Replace aa_ajax_object and nonce with actual keys found in step 1).

5. Exploitation Strategy

We will attempt to trigger the unauthorized dismissal of a notice.

  • Step 1: Discover Hooks: Run grep -r "wp_ajax_nopriv" . to find all unauthenticated AJAX actions.
  • Step 2: Analyze Handler: Check the identified handler function for a lack of current_user_can().
  • Step 3: Craft Payload:
    • URL: http://<target>/wp-admin/admin-ajax.php
    • Method: POST
    • Content-Type: application/x-www-form-urlencoded
    • Body: action=aa_dismiss_notice&notice_id=security_update_check&_wpnonce=<NONCE_FROM_STEP_4>
  • Step 4: Execute: Send the request using the http_request tool.

6. Test Data Setup

  1. Install Plugin: Ensure Author Avatars List v2.1.25 is installed.
  2. Generate a Notice: Some plugins only show notices if certain conditions are met (e.g., a specific setting is empty). Check the code for add_action( 'admin_notices', ... ).
  3. Create Nonce Page:
    wp post create --post_type=page --post_title="Nonce Page" --post_status=publish --post_content='[author_avatars]'

7. Expected Results

  • Response: The server returns a 200 OK or a JSON success message (e.g., {"success":true}).
  • System State: The administrative notice is no longer visible to the admin, or the corresponding database entry in wp_options is updated.

8. Verification Steps

After the exploit, use WP-CLI to verify the change in the database:

  1. Check Options: wp option get author_avatars_dismissed_notices (inferred option name).
  2. Verify Presence: Confirm that the notice_id used in the exploit now exists in the dismissed list.
  3. Visual Check: Login as admin and verify the notice is gone.

9. Alternative Approaches

If aa_dismiss_notice is not the vulnerable action:

  1. Search for admin_init: Search for functions hooked to admin_init that perform update_option. These are often vulnerable if they lack is_admin() or capability checks.
    • grep -r "add_action.*admin_init" .
  2. Search for aa_save_settings: Check if unauthenticated users can update global plugin settings via AJAX.
  3. SSRF/Information Leak: If the CVSS vector is misinterpreted and C:L exists, check aa_render_user_list for unauthorized user enumeration.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Author Avatars List/Block plugin for WordPress is vulnerable to unauthorized data modification because it lacks a capability check on its AJAX notice dismissal handler. This allows unauthenticated attackers to permanently dismiss administrative notices, potentially hiding critical security warnings or plugin configuration requirements from site administrators.

Vulnerable Code

// lib/AuthorAvatars.class.php (inferred)
add_action( 'wp_ajax_nopriv_aa_dismiss_notice', array( $this, 'ajax_dismiss_notice' ) );

public function ajax_dismiss_notice() {
    $notice_id = isset( $_POST['notice_id'] ) ? sanitize_text_field( $_POST['notice_id'] ) : '';
    if ( ! empty( $notice_id ) ) {
        $dismissed_notices = get_option( 'aa_dismissed_notices', array() );
        $dismissed_notices[] = $notice_id;
        update_option( 'aa_dismissed_notices', $dismissed_notices );
        wp_send_json_success();
    }
    wp_send_json_error();
}

Security Fix

--- a/lib/AuthorAvatars.class.php
+++ b/lib/AuthorAvatars.class.php
@@ -1,5 +1,11 @@
 public function ajax_dismiss_notice() {
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
+        return;
+    }
+
+    check_ajax_referer( 'aa_dismiss_notice_nonce', 'security' );
+
     $notice_id = isset( $_POST['notice_id'] ) ? sanitize_text_field( $_POST['notice_id'] ) : '';

Exploit Outline

1. Identify the target site running Author Avatars List/Block <= 2.1.25. 2. Locate a public-facing page that renders the plugin's shortcode [author_avatars] to check if a nonce is localized for the 'aa_dismiss_notice' action. 3. Extract the AJAX nonce from the page source if available (e.g., within the window.aa_ajax_object script block). 4. Send a POST request to /wp-admin/admin-ajax.php with the following parameters: action=aa_dismiss_notice, notice_id=security_update_check (or any valid notice identifier), and security=[extracted_nonce]. 5. If the request returns success, the specified notice is added to the site's dismissed list in the database, preventing administrators from seeing it.

Check if your site is affected.

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