Vulnerability: An issue was discovered in the VeronaLabs wp-statistics plugin before 12.6.7 for WordPress. The v1/hit endpoint of the API, when the non-default "use cache plugin" setting is enabled, is vulnerable to unauthenticated blind SQL Injection.
Vulnerability ID: CVE-2019-13275
CWE: CWE-89
Severity score: 6.4
Project: https://github.com/wp-statistics/wp-statistics
Published: 2019-07-04
File: includes/class-wp-statistics-pages.php
Commit message: Check Prepare Parameter in CURD wpdb #286
Commit author: Mehrshad Darzi

Vulnerable version (before fix):
 public static function record() { 		$page_uri = self::sanitize_page_uri();  		// Check if we have already been to this page today. 		$exist = $wpdb->get_row( "SELECT `page_id` FROM `" . DB::table( 'pages' ) . "` WHERE `date` = '" . TimeZone::getCurrentDate( 'Y-m-d' ) . "' " . ( array_key_exists( "search_query", $current_page ) === true ? "AND `uri` = '" . $page_uri . "'" : "" ) . "AND `type` = '{$current_page['type']}' AND `id` = {$current_page['id']}", ARRAY_A );  		// Update Exist Page 		if ( null !== $exist ) {  			$wpdb->query( $wpdb->prepare( "UPDATE `" . DB::table( 'pages' ) . "` SET `count` = `count` + 1 WHERE `date` = '" . TimeZone::getCurrentDate( 'Y-m-d' ) . "' " . ( array_key_exists( "search_query", $current_page ) === true ? "AND `uri` = '" . $page_uri . "'" : "" ) . "AND `type` = '{$current_page['type']}' AND `id` = %d", $current_page['id'] ) ); 			$page_id = $exist['page_id'];  		} else {

Fixed version (after fix):
 public static function record() { 		$page_uri = self::sanitize_page_uri();  		// Check if we have already been to this page today. 		$exist = $wpdb->get_row( "SELECT `page_id` FROM `" . DB::table( 'pages' ) . "` WHERE `date` = '" . TimeZone::getCurrentDate( 'Y-m-d' ) . "' " . ( array_key_exists( "search_query", $current_page ) === true ? "AND `uri` = '" . esc_sql( $page_uri ) . "'" : "" ) . "AND `type` = '{$current_page['type']}' AND `id` = {$current_page['id']}", ARRAY_A );  		// Update Exist Page 		if ( null !== $exist ) {  			$wpdb->query( $wpdb->prepare( "UPDATE `" . DB::table( 'pages' ) . "` SET `count` = `count` + 1 WHERE `date` = '" . TimeZone::getCurrentDate( 'Y-m-d' ) . "' " . ( array_key_exists( "search_query", $current_page ) === true ? "AND `uri` = '" . esc_sql( $page_uri ) . "'" : "" ) . "AND `type` = '{$current_page['type']}' AND `id` = %d", $current_page['id'] ) ); 			$page_id = $exist['page_id'];  		} else {

Patch:
patch: @@ -215,12 +215,12 @@ public static function record() {
 		$page_uri = self::sanitize_page_uri();
 
 		// Check if we have already been to this page today.
-		$exist = $wpdb->get_row( "SELECT `page_id` FROM `" . DB::table( 'pages' ) . "` WHERE `date` = '" . TimeZone::getCurrentDate( 'Y-m-d' ) . "' " . ( array_key_exists( "search_query", $current_page ) === true ? "AND `uri` = '" . $page_uri . "'" : "" ) . "AND `type` = '{$current_page['type']}' AND `id` = {$current_page['id']}", ARRAY_A );
+		$exist = $wpdb->get_row( "SELECT `page_id` FROM `" . DB::table( 'pages' ) . "` WHERE `date` = '" . TimeZone::getCurrentDate( 'Y-m-d' ) . "' " . ( array_key_exists( "search_query", $current_page ) === true ? "AND `uri` = '" . esc_sql( $page_uri ) . "'" : "" ) . "AND `type` = '{$current_page['type']}' AND `id` = {$current_page['id']}", ARRAY_A );
 
 		// Update Exist Page
 		if ( null !== $exist ) {
 
-			$wpdb->query( $wpdb->prepare( "UPDATE `" . DB::table( 'pages' ) . "` SET `count` = `count` + 1 WHERE `date` = '" . TimeZone::getCurrentDate( 'Y-m-d' ) . "' " . ( array_key_exists( "search_query", $current_page ) === true ? "AND `uri` = '" . $page_uri . "'" : "" ) . "AND `type` = '{$current_page['type']}' AND `id` = %d", $current_page['id'] ) );
+			$wpdb->query( $wpdb->prepare( "UPDATE `" . DB::table( 'pages' ) . "` SET `count` = `count` + 1 WHERE `date` = '" . TimeZone::getCurrentDate( 'Y-m-d' ) . "' " . ( array_key_exists( "search_query", $current_page ) === true ? "AND `uri` = '" . esc_sql( $page_uri ) . "'" : "" ) . "AND `type` = '{$current_page['type']}' AND `id` = %d", $current_page['id'] ) );
 			$page_id = $exist['page_id'];
 
 		} else {
path: includes/class-wp-statistics-pages.php