Introduction
Cross-Site Scripting (XSS) vulnerabilities continue to be one of the most common security flaws in web applications. Recently, I identified a Reflected XSS vulnerability in the WordPress plugin “Appointment Booking Calendar — Simply Schedule Appointments,” affecting all versions up to 1.6.8.3.
Relevant Information:
- Plugin: Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin
- Affected Versions: <= 1.6.8.3
- CVE: CVE-2024-13431
- CWE: CWE-79 (Improper Neutralization of Input During Web Page Generation)
- CVSS: 6.1 (Medium) – CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- Publication Date: March 6, 2025 (Wordfence Intelligence)
The Plugin and the Vulnerability
Simply Schedule Appointments
Simply Schedule Appointments is a WordPress plugin with over 50,000 active installations that offers automatic appointment scheduling features. It allows business clients to book appointments directly through the website.
The Vulnerability
The vulnerability found allows an attacker, without the need for authentication, to perform Reflected Cross-Site Scripting (XSS) attacks through the accent_color and background parameters in the /wp-json/ssa/v1/embed-inner endpoint. Due to the lack of proper sanitization of these parameters, it’s possible to inject malicious JavaScript code that will be executed in the victim’s browser when they access specially crafted URLs.
Technical Analysis
The vulnerability lies in how the plugin processes color parameters. In the class-styles.php file, the hex_to_rgba() function is used to convert hexadecimal values to RGBA format:
/**
* Transforms an hex color into rgba, necessary to calculate contrast.
*
* @since 3.7.6
*
* @param string $hex_string
* @return string
*/
public function hex_to_rgba( $hex_string ) {
// remove hash sign if it's passed on the hex string
$hex_string = ltrim($hex_string, '#');
$color_type = $this->is_hex_or_rgba( $hex_string );
// if not a valid hex or rgba color, return
if( ! $color_type ) {
return null;
}
if( $color_type === 'rgba' ) {
return $hex_string;
}
if( strlen( $hex_string ) === 6 ) {
sscanf($hex_string, "%02x%02x%02x", $r, $g, $b);
} else {
$r = hexdec(str_repeat($hex_string[0], 2));
$g = hexdec(str_repeat($hex_string[1], 2));
$b = hexdec(str_repeat($hex_string[2], 2));
}
return "rgba($r,$g,$b,1)";
}
The main issue is in the is_hex_or_rgba() method, which checks if a string is a valid hexadecimal or RGBA value:
/**
* checks if a string is a valid hex color or rgba.
*
* @since 3.7.6
*
* @param string $color
* @return string|boolean
*/
public function is_hex_or_rgba( $color ) {
if( strpos( $color, 'rgba' ) !== false ) {
return 'rgba';
}
if( preg_match('/^#?(([a-f0-9]{3}){1,2})$/i', $color ) ) {
return 'hex';
}
return null;
}
This function has a critical flaw: if the string contains “rgba”, the function classifies it as a valid RGBA value without performing any further format validation. This allows an attacker to inject any string containing “rgba” followed by malicious code, which will be returned without sanitization by the hex_to_rgba() method.
In the implementation of the /wp-json/ssa/v1/embed-inner endpoint, the code processes the values of the accent_color and background parameters directly from the GET request:
if( isset( $_GET['background'] ) && ! empty( $_GET['background'] ) ) {
$background = $ssa->styles->hex_to_rgba( '#'. $_GET['background'] );
if( $background ) {
$styles_params['background'] = $background;
}
}
This implementation allows an attacker to insert a value like ffffffrgba;</style><script>alert(1)</script>, which will be processed as a valid RGBA value and returned without sanitization, resulting in an XSS attack when the JavaScript is executed in the victim’s browser.
Proof of Concept (POC)
During my testing of the plugin, I was able to demonstrate the vulnerability with the following URL:
http://example.com/wp-json/ssa/v1/embed-inner?background=ffffffrgba;</style><script>alert(1)</script>
By accessing this URL in a browser, the JavaScript script alert(1) is executed, confirming the existence of the Reflected XSS vulnerability.
Impact and Risks
This Reflected XSS vulnerability can have several negative impacts:
- Theft of session cookies and account hijacking (session hijack)
- Redirection to malicious websites
- Display of fraudulent content to users
- Modification of page content to perform phishing attacks
- Execution of unauthorized actions within the context of a logged-in user
The impact is amplified by the fact that the vulnerability does not require authentication to be exploited and can be easily embedded in malicious links sent via email, messages, or social media.
How It Was Fixed
In version 1.6.8.5, the developers implemented a new sanitization function, ssa_sanitize_color_input(), which performs more rigorous validation of color values:
/**
* Sanitizes the accent color input.
*
* @param string $color The input color string.
* @return string|null The sanitized color or null if the input is invalid.
*/
function ssa_sanitize_color_input($color) {
$hex_pattern = '/^[a-fA-F0-9]+$/';
$rgba_pattern = '/^rgba\(\d{1,3},\d{1,3},\d{1,3},(?:0|1|0?\.\d+)\)$/i';
if (preg_match($hex_pattern, $color) && in_array(strlen($color), [6, 3])) {
return strtolower($color);
}
if (preg_match($rgba_pattern, $color)) {
return $color;
}
return null;
}
The new implementation uses stricter regular expressions to validate both hexadecimal and RGBA format values:
- For hexadecimal colors: It checks if the value contains only hexadecimal characters (a-f, A-F, 0-9) and has exactly 3 or 6 characters.
- For RGBA colors: It validates that the format strictly follows the pattern
rgba(R,G,B,A)where R, G, and B are numbers from 0 to 255, and A is a value between 0 and 1.
Additionally, the function returns null for any input that does not pass validation, preventing malicious values from being processed by the plugin.
The code has been modified to use this sanitization function before passing values to hex_to_rgba():
if( isset( $_GET['background'] ) && ! empty( $_GET['background'] ) ) {
$background_input = ssa_sanitize_color_input( $_GET['background'] );
$background = $ssa->styles->hex_to_rgba( '#'. $background_input );
// ... rest of the code
}
Conclusion
CVE-2024-13431 highlights the importance of implementing proper validation and sanitization of user inputs, especially in plugins with a large number of installations. The vulnerability has been fixed in version 1.6.8.5 of Simply Schedule Appointments, and all users are strongly advised to update to this version or later.
I would like to thank the Wordfence Intelligence team for their professionalism during the disclosure process and the developers of Simply Schedule Appointments for the swift implementation of an effective fix.
This post is based on my discovery of CVE-2024-13431, documented in the Wordfence Intelligence vulnerability database. If you have any questions or comments, please leave them below or contact me directly.