CVE-2016-9287: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: In /framework/modules/notfound/controllers/notfoundController.php of Exponent CMS 2.4.0 patch1, untrusted input is passed into getSearchResults. The method getSearchResults is defined in the search model with the parameter '$term' used directly in SQL. Impact is a SQL injection.
CWE 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.
CVSS v3 base score: 9.8
Published: 2016-11-15T11:59Z
Repository: https://github.com/exponentcms/exponent-cms
Language: PHP
Files changed: framework/modules/notfound/controllers/notfoundController.php
Commit date: 2016-11-05 21:04:06 -0400
Commit message: fix sql injection issue in notfound controller; reported by pang0lin

Diff: diff --git a/framework/modules/notfound/controllers/notfoundController.php b/framework/modules/notfound/controllers/notfoundController.php
index 87d9486379b..fc8bab066b7 100755
--- a/framework/modules/notfound/controllers/notfoundController.php
+++ b/framework/modules/notfound/controllers/notfoundController.php
@@ -30,18 +30,18 @@ class notfoundController extends expController {
     static function displayname() { return gt("Page Not Found"); }
     static function description() { return gt("This controller handles routing to the appropriate place when pages are not found."); }
     static function hasSources() { return false; }
     static function hasViews() { return false; }
     static function hasContent() { return false; }
-    
+
     public function handle() {
         global $router;
 
-        $args = array_merge(array('controller'=>'notfound', 'action'=>'page_not_found'), $router->url_parts);   
+        $args = array_merge(array('controller'=>'notfound', 'action'=>'page_not_found'), $router->url_parts);
         header("Refresh: 0; url=".$router->makeLink($args), false, 404);
     }
-    
+
     public function page_not_found() {
         global $router;
 
         header(':', true, 404);
         $params = $router->params;
@@ -58,11 +58,11 @@ class notfoundController extends expController {
 	    );
         // If magic quotes is on and the user uses modifiers like " (quotes) they get escaped. We don't want that in this case.
         if (get_magic_quotes_gpc()) {
             $terms = stripslashes($terms);
         }
-        $terms = htmlspecialchars($terms);
+        $terms = expString::escape(htmlspecialchars($terms));
 
         // check for server requested error documents here instead of treating them as a search request
         if ($terms == SITE_404_FILE) {
             self::handle_not_found();
         } elseif ($terms == SITE_403_FILE) {

Vulnerable code:     
        $args = array_merge(array('controller'=>'notfound', 'action'=>'page_not_found'), $router->url_parts);   
    
        $terms = htmlspecialchars($terms);
Fixed code: 
        $args = array_merge(array('controller'=>'notfound', 'action'=>'page_not_found'), $router->url_parts);

        $terms = expString::escape(htmlspecialchars($terms));