CVE-2018-25076 (published 2023-01-16T12:15Z)

A vulnerability classified as critical was found in Events Extension on BigTree. Affected by this vulnerability is the function getRandomFeaturedEventByDate/getUpcomingFeaturedEventsInCategoriesWithSubcategories/recacheEvent/searchResults of the file classes/events.php. The manipulation leads to sql injection. The patch is named 11169e48ab1249109485fdb1e0c9fca3d25ba01d. It is recommended to apply a patch to fix this issue. The associated identifier of this vulnerability is VDB-218395.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/timbuckingham/bigtree-events
commit_details: repo_url: https://github.com/timbuckingham/bigtree-events
author: Tim Buckingham
author_date: 2018-03-19 11:03:37-04:00
msg: Added methods for getting a page of upcoming events, fixed SQL injection in searches
repository: repo_url: https://github.com/timbuckingham/bigtree-events
repo_name: timbuckingham/bigtree-events
description: An Events extension for BigTree CMS.
repo_language: PHP
owner: timbuckingham
file_changes: filename: events.php
change_type: ModificationType.MODIFY
diff: @@ -1012,14 +1012,16 @@
 
 		static function getSearchResultsInDateRange($query,$start_date,$end_date,$featured = false) {
 			$events = array();
+			$words = explode(" ",$query);
+			$qwords = array();
+
 			if ($featured) {
 				$featured = " AND btx_events_events.featured = 'on' ";
 			}
 
-			$words = explode(" ",$query);
-			$qwords = array();
 			if ($words) {
 				foreach ($words as $word) {
+					$word = sqlescape($word);
 					$qwords[] = "(btx_events_events.title LIKE '%$word%' OR btx_events_events.description LIKE '%$word%')";
 				}
 				$qwords = implode(" AND ",$qwords)." AND ";
@@ -1296,32 +1298,116 @@
 				An array of event instances ordered by soonest.
 		*/
 
-		static function getUpcomingSearchResults($query,$limit = 5,$featured = false) {
+		static function getUpcomingSearchResults($query, $limit = 5, $featured = false) {
 			$events = array();
+			$qwords = array();
+			$words = explode(" ",$query);
+
 			if ($featured) {
 				$featured = " AND btx_events_events.featured = 'on' ";
 			}
 
+			if ($words) {
+				foreach ($words as $word) {
+					$word = sqlescape($word);
+					$qwords[] = "(btx_events_events.title LIKE '%$word%' OR btx_events_events.description LIKE '%$word%')";
+				}
+
+				$qwords = implode(" AND ",$qwords)." AND ";
+			} else {
+				$qwords = "";
+			}
+
+			$q = sqlquery("SELECT btx_events_date_cache.start,btx_events_date_cache.end,btx_events_date_cache.id as instance,btx_events_date_cache.title_route AS title_route, btx_events_date_cache.date_route AS date_route,btx_events_events.* FROM btx_events_events JOIN btx_events_date_cache WHERE btx_events_date_cache.event = btx_events_events.id AND $qwords btx_events_date_cache.end >= NOW() $featured ORDER BY btx_events_date_cache.start ASC LIMIT $limit");
+
+			while ($f = sqlfetch($q)) {
+				$event = self::get($f);
+				$events[] = $event;
+			}
+			return $events;
+		}
+
+		/*
+			Function: getUpcomingSearchResultsPage
+				Returns a page of event instances matching a given query that are occurring in the future.
+			
+			Parameters:
+				query - The string to search for.
+				page - The page to return
+				per_page - The number of event instances to return per page.
+			
+			Returns:
+				An array of event instances ordered by soonest.
+		*/
+
+		static function getUpcomingSearchResultsPage($query, $page = 1, $per_page = 10) {
+			$events = array();
 			$words = explode(" ",$query);
 			$qwords = array();
+
 			if ($words) {
 				foreach ($words as $word) {
+					$word = sqlescape($word);
 					$qwords[] = "(btx_events_events.title LIKE '%$word%' OR btx_events_events.description LIKE '%$word%')";
 				}
+
 				$qwords = implode(" AND ",$qwords)." AND ";
 			} else {
 				$qwords = "";
 			}
 
-			$q = sqlquery("SELECT btx_events_date_cache.start,btx_events_date_cache.end,btx_events_date_cache.id as instance,btx_events_date_cache.title_route AS title_route, btx_events_date_cache.date_route AS date_route,btx_events_events.* FROM btx_events_events JOIN btx_events_date_cache WHERE btx_events_date_cache.event = btx_events_events.id AND $qwords btx_events_date_cache.end >= NOW() $featured ORDER BY btx_events_date_cache.start ASC LIMIT $limit");
+			$limit = (($page - 1) * $per_page).", $per_page";
+
+			$q = sqlquery("SELECT btx_events_date_cache.start,btx_events_date_cache.end,btx_events_date_cache.id as instance,btx_events_date_cache.title_route AS title_route, btx_events_date_cache.date_route AS date_route,btx_events_events.* FROM btx_events_events JOIN btx_events_date_cache WHERE btx_events_date_cache.event = btx_events_events.id AND $qwords btx_events_date_cache.end >= NOW() ORDER BY btx_events_date_cache.start ASC LIMIT $limit");
 
 			while ($f = sqlfetch($q)) {
 				$event = self::get($f);
 				$events[] = $event;
 			}
+
 			return $events;
 		}
 
+		/*
+			Function: getUpcomingSearchResultsPage
+				Returns the number of pages of event instances matching a given query that are occurring in the future.
+			
+			Parameters:
+				query - The string to search for.
+				per_page - The number of event instances per page.
+			
+			Returns:
+				An integer.
+		*/
+
+		static function getUpcomingSearchResultsPageCount($query, $per_page = 10) {
+			$events = array();
+			$words = explode(" ",$query);
+			$qwords = array();
+
+			if ($words) {
+				foreach ($words as $word) {
+					$word = sqlescape($word);
+					$qwords[] = "(btx_events_events.title LIKE '%$word%' OR btx_events_events.description LIKE '%$word%')";
+				}
+				
+				$qwords = implode(" AND ",$qwords)." AND ";
+			} else {
+				$qwords = "";
+			}
+
+			$limit = (($page - 1) * $per_page).", $per_page";
+
+			$f = sqlfetch(sqlquery("SELECT COUNT(btx_events_date_cache.id) AS `count`
+									FROM btx_events_events JOIN btx_events_date_cache
+									ON btx_events_date_cache.event = btx_events_events.id
+									WHERE $qwords btx_events_date_cache.end >= NOW()"));
+
+			$pages = ceil($f["count"] / $per_page);
+
+			return $pages ?: 1;
+		}
+
 		/*
 			Function: getUpcomingFeaturedSearchResults
 				Returns featured event instances matching a given query that are occurring in the future.
@@ -1365,10 +1451,13 @@
 		static function searchResults($query) {
 			$words = explode(" ",$query);
 			$qwords = array();
+
 			if ($words) {
 				foreach ($words as $word) {
+					$word = sqlescape($word);
 					$qwords[] = "(title LIKE '%$word%' OR description LIKE '%$word%')";
 				}
+
 				$qwords = " AND ".implode(" AND ",$qwords);
 			} else {
 				$qwords = "";
@@ -1377,10 +1466,12 @@
 			$q = sqlquery("SELECT * FROM btx_events_events WHERE 1 $qwords ORDER BY id DESC");
 
 			$events = array();
+
 			while ($f = sqlfetch($q)) {
 				$event = self::get($f);
 				$events[] = $event;
 			}
+
 			return $events;
 		}
 
@@ -1396,21 +1487,24 @@
 				An array of decoded event entries from the database.
 		*/
 
-		static function searchResultsInCategory($query,$category) {
+		static function searchResultsInCategory($query, $category) {
 			$category = is_array($category) ? sqlescape($category["id"]) : sqlescape($category);
 			$with_sub = array_merge(array($category),self::getSubcategoriesOfCategory($category));
-
 			$cat_search = array();
+
 			foreach ($with_sub as $category) {
 				$cat_search[] = "btx_events_event_categories.category = '$category'";
 			}
 
 			$words = explode(" ",$query);
 			$qwords = array();
+
 			if ($words) {
 				foreach ($words as $word) {
+					$word = sqlescape($word);
 					$qwords[] = "(btx_events_events.title LIKE '%$word%' OR btx_events_events.description LIKE '%$word%')";
 				}
+
 				$qwords = " AND ".implode(" AND ",$qwords);
 			} else {
 				$qwords = "";
@@ -1419,10 +1513,12 @@
 			$q = sqlquery("SELECT DISTINCT(btx_events_event_categories.event),btx_events_events.* FROM btx_events_events JOIN btx_events_event_categories WHERE btx_events_events.id = btx_events_event_categories.event $qwords AND (".implode(" OR ",$cat_search).") ORDER BY id DESC");
 
 			$events = array();
+
 			while ($f = sqlfetch($q)) {
 				$event = self::get($f);
 				$events[] = $event;
 			}
+
 			return $events;
 		}
 		

programming_language: PHP
filename: manifest.json
change_type: ModificationType.MODIFY
diff: @@ -2,7 +2,7 @@
     "type": "extension",
     "id": "com.fastspot.events",
     "version": "1.2.1",
-    "revision": 7,
+    "revision": 6,
     "compatibility": "4.2.4+",
     "title": "Events",
     "description": "A very fast (performance wise) events system that supports recurring events and a powerful class for pulling events into the front end of your site.",
@@ -372,10 +372,10 @@
             }
         ],
         "tables": {
-            "btx_events_categories": "CREATE TABLE `btx_events_categories` (   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,   `parent` int(11) unsigned DEFAULT NULL,   `name` varchar(255) NOT NULL DEFAULT '',   `route` varchar(255) NOT NULL DEFAULT '',   `position` int(11) unsigned NOT NULL,   PRIMARY KEY (`id`),   KEY `parent` (`parent`),   KEY `route` (`route`),   KEY `position` (`position`),    FOREIGN KEY (`parent`) REFERENCES `btx_events_categories` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8",
-            "btx_events_date_cache": "CREATE TABLE `btx_events_date_cache` (   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,   `event` int(11) unsigned NOT NULL,   `start` datetime NOT NULL,   `end` datetime NOT NULL,   `date_cached` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,   `title_route` varchar(255) NOT NULL DEFAULT '',   `date_route` varchar(255) NOT NULL DEFAULT '',   PRIMARY KEY (`id`),   KEY `event` (`event`),   KEY `start` (`start`),   KEY `end` (`end`),   KEY `title_route` (`title_route`),   KEY `date_route` (`date_route`),   KEY `date_cached` (`date_cached`),    FOREIGN KEY (`event`) REFERENCES `btx_events_events` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8",
-            "btx_events_event_categories": "CREATE TABLE `btx_events_event_categories` (   `event` int(11) unsigned NOT NULL,   `category` int(11) unsigned NOT NULL,   KEY `event` (`event`),   KEY `category` (`category`),    FOREIGN KEY (`event`) REFERENCES `btx_events_events` (`id`) ON DELETE CASCADE,    FOREIGN KEY (`category`) REFERENCES `btx_events_categories` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8",
-            "btx_events_events": "CREATE TABLE `btx_events_events` (   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,   `title` varchar(255) NOT NULL DEFAULT '',   `description` mediumtext NOT NULL,   `image` varchar(255) NOT NULL,   `start_date` date DEFAULT NULL,   `end_date` date DEFAULT NULL,   `start_time` time DEFAULT NULL,   `end_time` time DEFAULT NULL,   `all_day` char(2) NOT NULL,   `recurrence_type` varchar(255) NOT NULL,   `recurrence_detail` varchar(255) NOT NULL,   `canceled_recurrences` text NOT NULL,   `recurring_end_date` date DEFAULT NULL,   `last_updated` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,   `featured` char(2) NOT NULL,   `route` varchar(255) DEFAULT NULL,   PRIMARY KEY (`id`),   KEY `start_date` (`start_date`),   KEY `end_date` (`end_date`),   KEY `recurring_end_date` (`recurring_end_date`),   KEY `recurrence_type` (`recurrence_type`),   KEY `featured` (`featured`),   KEY `route` (`route`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8"
+            "btx_events_categories": "CREATE TABLE `btx_events_categories` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `parent` int(11) DEFAULT NULL,   `name` varchar(255) NOT NULL DEFAULT '',   `route` varchar(255) NOT NULL DEFAULT '',   `position` int(11) NOT NULL,   PRIMARY KEY (`id`),   KEY `parent` (`parent`),   KEY `route` (`route`),   KEY `position` (`position`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8",
+            "btx_events_date_cache": "CREATE TABLE `btx_events_date_cache` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `event` int(11) NOT NULL,   `start` datetime NOT NULL,   `end` datetime NOT NULL,   `date_cached` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,   `title_route` varchar(255) NOT NULL DEFAULT '',   `date_route` varchar(255) NOT NULL DEFAULT '',   PRIMARY KEY (`id`),   KEY `event` (`event`),   KEY `start` (`start`),   KEY `end` (`end`),   KEY `title_route` (`title_route`),   KEY `date_route` (`date_route`),   KEY `date_cached` (`date_cached`),    FOREIGN KEY (`event`) REFERENCES `btx_events_events` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8",
+            "btx_events_event_categories": "CREATE TABLE `btx_events_event_categories` (   `event` int(11) NOT NULL,   `category` int(11) NOT NULL,   KEY `event` (`event`),   KEY `category` (`category`),    FOREIGN KEY (`event`) REFERENCES `btx_events_events` (`id`) ON DELETE CASCADE,    FOREIGN KEY (`category`) REFERENCES `btx_events_categories` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8",
+            "btx_events_events": "CREATE TABLE `btx_events_events` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `title` varchar(255) NOT NULL DEFAULT '',   `description` mediumtext NOT NULL,   `image` varchar(255) NOT NULL,   `start_date` date DEFAULT NULL,   `end_date` date DEFAULT NULL,   `start_time` time DEFAULT NULL,   `end_time` time DEFAULT NULL,   `all_day` char(2) NOT NULL,   `recurrence_type` varchar(255) NOT NULL,   `recurrence_detail` varchar(255) NOT NULL,   `canceled_recurrences` text NOT NULL,   `recurring_end_date` date DEFAULT NULL,   `last_updated` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,   `featured` char(2) NOT NULL,   `route` varchar(255) DEFAULT NULL,   PRIMARY KEY (`id`),   KEY `start_date` (`start_date`),   KEY `end_date` (`end_date`),   KEY `recurring_end_date` (`recurring_end_date`),   KEY `recurrence_type` (`recurrence_type`),   KEY `featured` (`featured`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8"
         }
     },
     "sql_revisions": []

programming_language: Python