Author Avatars List/Block <= 2.1.25 - Missing Authorization
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:NTechnical Details
<=2.1.25This 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 similaraa_*prefixed action. - Parameter:
notice_idorid. - 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
- 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' ) ); - Entry Point: An unauthenticated user sends a POST request to
admin-ajax.phpwithaction=aa_dismiss_notice. - Missing Check: The
ajax_dismiss_noticefunction executes without callingcurrent_user_can( 'manage_options' ). - Sink: The function calls
update_option()orset_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.
- Identify the Script: Look for
wp_localize_scriptin the codebase.- Command:
grep -r "wp_localize_script" .
- Command:
- Locate the Key: Identify the object name and key (e.g.,
window.author_avatars_settings?.nonce). - 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]'
- 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")(Replaceaa_ajax_objectandnoncewith 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¬ice_id=security_update_check&_wpnonce=<NONCE_FROM_STEP_4>
- URL:
- Step 4: Execute: Send the request using the
http_requesttool.
6. Test Data Setup
- Install Plugin: Ensure Author Avatars List v2.1.25 is installed.
- 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', ... ). - 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 OKor 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_optionsis updated.
8. Verification Steps
After the exploit, use WP-CLI to verify the change in the database:
- Check Options:
wp option get author_avatars_dismissed_notices(inferred option name). - Verify Presence: Confirm that the
notice_idused in the exploit now exists in the dismissed list. - Visual Check: Login as admin and verify the notice is gone.
9. Alternative Approaches
If aa_dismiss_notice is not the vulnerable action:
- Search for
admin_init: Search for functions hooked toadmin_initthat performupdate_option. These are often vulnerable if they lackis_admin()or capability checks.grep -r "add_action.*admin_init" .
- Search for
aa_save_settings: Check if unauthenticated users can update global plugin settings via AJAX. - SSRF/Information Leak: If the CVSS vector is misinterpreted and
C:Lexists, checkaa_render_user_listfor unauthorized user enumeration.
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
@@ -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.