CVE-2016-7784: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: SQL injection vulnerability in the getSection function in framework/core/subsystems/expRouter.php in Exponent CMS 2.3.9 and earlier allows remote attackers to execute arbitrary SQL commands via the section parameter.
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: 2017-03-07T16:59Z
Repository: https://github.com/exponentcms/exponent-cms
Language: PHP
Files changed: framework/core/subsystems/expRouter.php, framework/modules/blog/controllers/blogController.php, framework/modules/search/controllers/searchController.php
Commit date: 2016-10-26 22:04:58 -0400
Commit message: fix a possible vulnerability and add some comments

Diff: diff --git a/framework/core/subsystems/expRouter.php b/framework/core/subsystems/expRouter.php
index b9ae99dff1..88d794bf67 100644
--- a/framework/core/subsystems/expRouter.php
+++ b/framework/core/subsystems/expRouter.php
@@ -39,11 +39,11 @@ class expRouter {
      * @var string
      */
     public  $url_style = '';
     public  $params = array();
     public  $sefPath = null;
-    
+
     function __construct() {
         self::getRouterMaps();
     }
 
     /**
@@ -52,15 +52,15 @@ class expRouter {
      * @param $fulllink
      *
      * @return string
      */
     public static function cleanLink($fulllink)
-    {           
-        if(substr($fulllink, -1) == '/') $fulllink = substr($fulllink, 0, -1);  
-        return $fulllink;                                   
+    {
+        if(substr($fulllink, -1) == '/') $fulllink = substr($fulllink, 0, -1);
+        return $fulllink;
     }
-    
+
     /**
 	 * Will build url to a module/page/etc (determined by what is passed to the $params array).
 	 *
 	 * @param array $params The params that are passed will determine what link is make
 	 *               section
@@ -80,33 +80,33 @@ class expRouter {
 	 */
     public function makeLink($params, $force_old_school=false, $secure=false, $no_map=false) {
         $secure = ENABLE_SSL == 1 ? $secure : false;  // check if this site can use SSL if not then force the link to not be secure
         $linkbase =  $secure ? URL_BASE_SECURE : URL_BASE;
         $linkbase .= SCRIPT_RELATIVE;
-                
-        if (isset($params['section']) && $params['section'] == SITE_DEFAULT_SECTION) {            
+
+        if (isset($params['section']) && $params['section'] == SITE_DEFAULT_SECTION) {
             return self::cleanLink($linkbase);
         }
 
         // Check to see if SEF_URLS have been turned on in the site config
         if (SEF_URLS == 1 && ($_SERVER["PHP_SELF"] == PATH_RELATIVE.'index.php' || $_SERVER["PHP_SELF"] == PATH_RELATIVE.'install/index.php') && $force_old_school == false) {
-            
-            if (isset($params['section']) && !isset($params['action'])) {                
+
+            if (isset($params['section']) && !isset($params['action'])) {
                 if (empty($params['sef_name'])) {
                     global $db;
 
                     $params['sef_name'] = $db->selectValue('section', 'sef_name', 'id='.intval($params['section']));
-                }                               
+                }
                 return self::cleanLink($linkbase.$params['sef_name']);
-            } else {                
+            } else {
                 // initialize the link
-                $link = '';               
-        
+                $link = '';
+
                 // we need to add the change the module parameter to controller if it exists
                 // we can remove this snippit once the old modules are gone.
                 if (!empty($params['module']) && empty($params['controller'])) $params['controller'] = $params['module'];
-            
+
                 // check to see if we have a router mapping for this controller/action
                 if (empty($no_map)){
                     for ($i = 0, $iMax = count($this->maps); $i < $iMax; $i++) {
                         $missing_params = array("dump");
 
@@ -128,11 +128,11 @@ class expRouter {
                 }
 
                 // if we found a mapping for this link then we can return it now.
                 //if ($link != '') return self::encode($linkbase.$link);
                 if ($link != '') return self::cleanLink($linkbase.$link);
-                
+
                 if (!empty($params['controller'])) $link .= $params['controller'].'/';
                 if (!empty($params['action'])) $link .= $params['action'].'/';
                 foreach ($params as $key=>$value) {
                     if(!is_array($value) && strpos($key,'__') !== 0 && $key !== 'PHPSESSID') {
                         $value = trim($value);
@@ -146,11 +146,11 @@ class expRouter {
                                 }
                             }
                         }
                     }
                 }
-                //trim last / off                 
+                //trim last / off
                 return self::cleanLink($linkbase.$link);
             }
         } else {
             // if the users don't have SEF URL's turned on then we make the link the old school way.
             if (!empty($params['sef_name'])) unset($params['sef_name']);
@@ -162,11 +162,11 @@ class expRouter {
                     if ($value != "") {
                         if ($key != 'src') {
                             $link .= urlencode($key)."=".urlencode($value)."&";
                         } else {
                             $link .= $key."=".$value."&";
-                        }                    
+                        }
                     }
                 }
             }
 
             $link = substr($link,0,-1);
@@ -233,15 +233,15 @@ class expRouter {
                 if (!$ret) $this->url_type = 'malformed';
             } elseif ($this->url_type == 'action') {
                 $this->isMappedURL();                       //check for a router map
                 $ret = $this->routeActionRequest();         // we didn't have a map for this URL.  Try to route it with this function.
 
-                // if this url wasn't a valid section, or action then kill it.  It might not actually be a "bad" url, 
+                // if this url wasn't a valid section, or action then kill it.  It might not actually be a "bad" url,
                 // but this is a precautionary measure against bad paths on images, css & js file, etc...with the new
                 // mod_rewrite rules these bad paths will not route thru here so we need to take them into account and
                 // deal with them accordingly.
-                if (!$ret) $this->url_type = 'malformed';  
+                if (!$ret) $this->url_type = 'malformed';
             } elseif ($this->url_type == 'post') {
                 // some forms aren't getting the controller field set right when the form is created
                 // we are putting this check here to safe guard against a controller being referred to as
                 // a module in the form.
                 if (!empty($_POST['controller']) || !empty($_POST['module'])) {
@@ -252,22 +252,22 @@ class expRouter {
                         $_REQUEST['controller'] = $module;
                     }
                 }
             }
         } elseif ($this->url_style == 'query' && SEF_URLS == 1 && !empty($_REQUEST['section']) && PRINTER_FRIENDLY != 1 && EXPORT_AS_PDF != 1) {
-            // if we hit this it's an old school url coming in and we're trying to use SEF's. 
+            // if we hit this it's an old school url coming in and we're trying to use SEF's.
             // we will send a permanent redirect so the search engines don't freak out about 2 links pointing
             // to the same page.
-            header("Location: ".$this->makeLink(array('section'=>intval($_REQUEST['section']))),TRUE,301);          
+            header("Location: ".$this->makeLink(array('section'=>intval($_REQUEST['section']))),TRUE,301);
         }
 
         // if this is a valid URL then we build out the current_url var which is used by flow, and possibly other places too
-        if ($this->url_type != 'malformed') {               
+        if ($this->url_type != 'malformed') {
             $this->current_url = $this->buildCurrentUrl();
         } else {
             // check if the URL is looking for a non-existent page or controller (we will check for bad action in renderAction())
-            // if page or controller is not found we will route to the not found controller.            
+            // if page or controller is not found we will route to the not found controller.
             $_REQUEST['controller'] = 'notfound';
             $_REQUEST['action'] = 'handle';
         }
     }
 
@@ -311,17 +311,17 @@ class expRouter {
         $this->url_parts = array();
         $this->buildSEFPath();
 
         if (!empty($this->sefPath)) {
             $this->url_style = 'sef';
-            $this->url_parts = explode('/', $this->sefPath);     
+            $this->url_parts = explode('/', $this->sefPath);
 
             // remove empty first and last url_parts if they exist
             //if (empty($this->url_parts[count($this->url_parts)-1])) array_pop($this->url_parts);
             if ($this->url_parts[count($this->url_parts)-1] == '') array_pop($this->url_parts);
             if (empty($this->url_parts[0])) array_shift($this->url_parts);
-            
+
             if (count($this->url_parts) < 1 || (empty($this->url_parts[0]) && count($this->url_parts) == 1) ) {
                 $this->url_type = 'base';  // no params
             } elseif (count($this->url_parts) == 1 || $db->selectObject('section', "sef_name='" . substr($this->sefPath,1) . "'") != null) {
                 $this->url_type = 'page';  // single param is page name
             } elseif ($_SERVER['REQUEST_METHOD'] == 'POST') {
@@ -353,90 +353,93 @@ class expRouter {
             }
         } else {
             $this->url_type = 'base';
             $this->params = array();
         }
-                              
+
         // Check if this was a printer friendly link request
-        define('PRINTER_FRIENDLY', (isset($_REQUEST['printerfriendly']) || isset($this->params['printerfriendly'])) ? 1 : 0);         
+        define('PRINTER_FRIENDLY', (isset($_REQUEST['printerfriendly']) || isset($this->params['printerfriendly'])) ? 1 : 0);
         define('EXPORT_AS_PDF', (isset($_REQUEST['exportaspdf']) || isset($this->params['exportaspdf'])) ? 1 : 0);
         define('EXPORT_AS_PDF_LANDSCAPE', (isset($_REQUEST['landscapepdf']) || isset($this->params['landscapepdf'])) ? 1 : 0);
     }
 
-    public function routePageRequest() {        
+    public function routePageRequest() {
 //        global $db;
 
         if ($this->url_type == 'base') {
             // if we made it in here this is a request for http://www.baseurl.com
             if (expTheme::inAction()) {
                 $_REQUEST['section'] = (expSession::is_set('last_section') ? expSession::get('last_section') : SITE_DEFAULT_SECTION);
             } else {
-                $_REQUEST['section'] = SITE_DEFAULT_SECTION;  
+                $_REQUEST['section'] = SITE_DEFAULT_SECTION;
             }
         } else {
             // Try to look up the page by sef_name first.  If that doesn't exist, strip out the dashes and
-            // check the regular page names.  If that still doesn't work then we'll redirect them to the 
+            // check the regular page names.  If that still doesn't work then we'll redirect them to the
             // search module using the page name as the search string.
             $section = $this->getPageByName(substr($this->sefPath,1));
             ########################################################
             #FJD TODO:  this needs further refinement
             #currently this requires a matching routerMap as such to work properly:
             /*
             $maps[] = array('controller'=>'store',
                     'action'=>'showall',
-                    'url_parts'=>array(                
+                    'url_parts'=>array(
                             'title'=>'(.*)'),
             );
             $maps[] = array('controller'=>'store',
                     'action'=>'showByTitle',
-                    'url_parts'=>array(                
+                    'url_parts'=>array(
                             'title'=>'(.*)'),
             );
             */
-            //if section is empty, we'll look for the page overrides first and route to 
+            //if section is empty, we'll look for the page overrides first and route to
             //routeActionRequest with some hand wacked variables. If we can't find an override
             //then we'll return false as usual
             // since we only received a single param and it wasn't a page, try for store category, or a product
             if (empty($section)) {
                 $sef_url = $this->url_parts[0];
                 //check for a category
-                $c = new storeCategory();                
+                $c = new storeCategory();
                 $cat = $c->findBy('sef_url', $sef_url);
                 if (empty($cat)) {
                     //check for a product
                     $p = new product();
                     $prod = $p->findBy('sef_url', $sef_url);
                     if(!empty($prod)) {
-                        //fake parts and route to action  
-                        $this->url_type = 'action';                   
+                        //fake parts and route to action
+                        $this->url_type = 'action';
                         $this->url_parts[0] = 'store'; //controller
-                        $this->url_parts[1] = 'show'; //controller
-                        $this->url_parts[2] = 'title'; //controller
-                        $this->url_parts[3] = $sef_url; //controller
+                        $this->url_parts[1] = 'show'; //action
+                        $this->url_parts[2] = 'title'; //param name
+                        $this->url_parts[3] = $sef_url; //param
                         //eDebug($this->url_parts,true);
                         $this->params = $this->convertPartsToParams();
                         return $this->routeActionRequest();
                     }
                     //else fall through
                 } else {
-                    //fake parts and route to action 
-                    $this->url_type = 'action';                                      
+                    //it's a store category
+                    //fake parts and route to action
+                    $this->url_type = 'action';
                     $this->url_parts[0] = 'store'; //controller
-                    $this->url_parts[1] = 'showall'; //controller
-                    $this->url_parts[2] = 'title'; //controller                    
-                    $this->url_parts[3] = $sef_url; //controller
+                    $this->url_parts[1] = 'showall'; //action
+                    $this->url_parts[2] = 'title'; //param name
+                    $this->url_parts[3] = $sef_url; //param
                     //eDebug($this->url_parts,true);
                     $this->params = $this->convertPartsToParams();
                     return $this->routeActionRequest();
                 }
+//fixme we may want to log missed pages (no existing store cat/product) requests and set up/use a redirect table (404)??
+//fixme and we may also want to log any redirects taken??
                 return false;
             }
             #########################################################
             //if (empty($section)) return false;  //couldnt find the page..let the calling action deal with it.
             $_REQUEST['section'] = $section->id;
         }
-        
+
         expHistory::set('viewable', array('section'=>intval($_REQUEST['section'])));
         return true;
     }
 
     /**
@@ -446,33 +449,33 @@ class expRouter {
         $part_count = count($this->url_parts);
         foreach ($this->maps as $map) {
             $matched = true;
             $pairs = array();
             $i = 0;
-            if ($part_count == count($map['url_parts'])) {               
+            if ($part_count == count($map['url_parts'])) {
                 foreach($map['url_parts'] as $key=>$map_part) {
                     $res = preg_match("/^$map_part/", $this->url_parts[$i]);
                     if ($res != 1) {
                         $matched = false;
                         break;
-                    } 
+                    }
                     $pairs[$key] = $this->url_parts[$i];
                     $i++;
                 }
             } else {
                 $matched = false;
-            }            
-              
+            }
+
             if ($matched) {
                 // safeguard against false matches when a real action was what the user really wanted.
                 if (count($this->url_parts) >= 2 && method_exists(expModules::getController($this->url_parts[0]), $this->url_parts[1]))
                     return false;
 
                 $this->url_parts = array();
                 $this->url_parts[0] = $map['controller'];
                 $this->url_parts[1] = $map['action'];
-        
+
                 if (isset($map['view'])) {
                     $this->url_parts[2] = 'view';
                     $this->url_parts[3] = $map['view'];
                 }
 
@@ -487,22 +490,22 @@ class expRouter {
                     if ($key != 'controller') {
                         $this->url_parts[] = $key;
                         $this->url_parts[] = $value;
                     }
                 }
-                
+
                 $this->params = $this->convertPartsToParams();
                 return true;
             }
         }
 
         return false;
     }
 
     public function routeActionRequest() {
         $return_params = array('controller'=>'','action'=>'','url_parts'=>array());
-    
+
         // If we have three url parts we assume they are controller->action->id, otherwise split them out into name<=>value pairs
         $return_params['controller'] = $this->url_parts[0]; // set the controller/module
         $return_params['action'] = $this->url_parts[1];     // set the action
 
         // Figure out if this is module or controller request - WE ONLY NEED THIS CODE UNTIL WE PULL OUT THE OLD MODULES
@@ -523,26 +526,26 @@ class expRouter {
             for ($i = 2, $iMax = count($this->url_parts); $i < $iMax; $i++) {
                 if ($i % 2 == 0) {
                     $return_params['url_parts'][$this->url_parts[$i]] = isset($this->url_parts[$i+1]) ? $this->url_parts[$i+1] : '';
                 }
             }
-        }        
+        }
 
         // Set the module or controller - this how the actual routing happens
         $_REQUEST[$requestType] = $return_params['controller']; //url_parts[0];
         $_GET[$requestType] = $return_params['controller'];
         $_POST[$requestType] = $return_params['controller'];
-    
+
         // Set the action for this module or controller
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-            // most of the time we can just grab the action outta the POST array since this is passed as a hidden field, 
+            // most of the time we can just grab the action outta the POST array since this is passed as a hidden field,
             // but sometimes it is actually set as the action on the form itself...then we get it from the params array instead.
             $action = !empty($_POST['action']) ? $_POST['action'] : $this->params['action'];
         } else {
             $action = $return_params['action'];
         }
-    
+
         $_REQUEST['action'] = $action;
         $_GET['action'] = $action;
         $_POST['action'] = $action;
 
         // pass off the name<=>value pairs
@@ -567,11 +570,11 @@ class expRouter {
 
     public static function encode($url) {
         $url = str_replace('&', 'and', $url);
         return preg_replace("/(-)$/", "", preg_replace('/(-){2,}/', '-', strtolower(preg_replace("/([^0-9a-z-_\+])/i", '-', $url))));
     }
-    
+
     public static function decode($url) {
         $url = str_replace('-', ' ', $url);
         return str_replace('+', '-', $url);
     }
 
@@ -621,12 +624,12 @@ class expRouter {
             $url .= '&printerfriendly=1\' , \'mywindow\',\'menubar=1,resizable=1,scrollbars=1,width='.$width.',height='.$height.'\');"';
             $url .= ' title="'.$title_text.'"';
             $url .= '> '.$link_text.'</a>';
             $url = str_replace('&ajax_action=1','',$url);
         }
-        
-        return $url; 
+
+        return $url;
     }
 
     public function exportAsPDFLink($link_text="Export as PDF", $class=null, $width=800, $height=600, $view='', $orientation=false, $limit='', $title_text="Export as PDF") {
         $url = '';
         if (EXPORT_AS_PDF != 1 && PRINTER_FRIENDLY != 1) {
@@ -693,11 +696,11 @@ class expRouter {
         return $params;
     }
 
     public function getPageByName($url_name) {
         global $db;
-        
+
         $section = null;
         if (is_numeric($url_name)) {
             $section = $db->selectObject('section', 'id=' . $url_name);
             if ($section == null) $section = $db->selectObject('section', "sef_name='" . $url_name . "'");
         } elseif ($this->url_type == 'base') {
@@ -715,11 +718,11 @@ class expRouter {
 #       } else {
 #           return $section;
 #       }
         return $section;
     }
-    
+
     private function buildSEFPath () {
         // Apache
         if (strpos($_SERVER['SERVER_SOFTWARE'],'Apache') !== false || strpos($_SERVER['SERVER_SOFTWARE'],'WebServerX') !== false) {
             switch(php_sapi_name()) {
                 case "cgi":
@@ -752,27 +755,27 @@ class expRouter {
         } elseif (strpos(strtolower($_SERVER['SERVER_SOFTWARE']),'nginx') !== false) {
             $this->sefPath = urldecode($_SERVER['REQUEST_URI']);
         } else {
             $this->sefPath = urldecode($_SERVER['REQUEST_URI']);
         }
-        
-        $this->sefPath = substr($this->sefPath,strlen(substr(PATH_RELATIVE,0,-1))); 
+
+        $this->sefPath = substr($this->sefPath,strlen(substr(PATH_RELATIVE,0,-1)));
         if (strpos($this->sefPath,'/index.php') === 0) {
             $this->sefPath = null;
         }
-        
+
 		//parse the ecommerce tracking code if present and include in the object
         if(isset($_SERVER['argv']) && is_array($_SERVER['argv']))
         {
             foreach($_SERVER['argv'] as $set)
             {
                 $s = explode("=",$set);
                 if($s[0] == "ectid")
                 {
-                    $this->ectid = $s[1];    
-                }   
-            }            
+                    $this->ectid = $s[1];
+                }
+            }
         }
         if (substr($this->sefPath,-1) == "/") $this->sefPath = substr($this->sefPath,0,-1);
         // sanitize it
         $sefPath = explode('">',$this->sefPath);  // remove any attempts to close the command
         $this->sefPath = expString::escape(expString::sanitize($sefPath[0]));
@@ -781,11 +784,11 @@ class expRouter {
     public function getSection() {
         global $db;
 
         if (expTheme::inAction()) {
             if (isset($_REQUEST['section'])) {
-                $section = $this->url_style=="sef" ? $this->getPageByName($_REQUEST['section'])->id : intval($_REQUEST['section']) ;
+                $section = $this->url_style=="sef" ? $this->getPageByName(expString::escape($_REQUEST['section']))->id : intval($_REQUEST['section']) ;
             } else {
                 $section = (expSession::is_set('last_section') ? expSession::get('last_section') : SITE_DEFAULT_SECTION);
             }
         } else {
             $section = (isset($_REQUEST['section']) ? intval($_REQUEST['section']) : SITE_DEFAULT_SECTION);
@@ -815,33 +818,33 @@ class expRouter {
         if (!$sectionObj->isPublic()) {
             define('PUBLIC_SECTION',0);
         } else {
             define('PUBLIC_SECTION',1);
         }
-    
+
         if (isset($_REQUEST['section'])) {
             expSession::set('last_section', intval($_REQUEST['section']));
         } elseif ($section == SITE_DEFAULT_SECTION) {
             expSession::set('last_section', intval(SITE_DEFAULT_SECTION));
         } else {
             //expSession::unset('last_section');
         }
         return $sectionObj;
     }
-    
+
     public function getRouterMaps() {
         $mapfile = BASE.'framework/core/router_maps.php';
 		if (file_exists(BASE.'themes/'.DISPLAY_THEME.'/router_maps.php')) {
 			$mapfile = BASE.'themes/'.DISPLAY_THEME.'/router_maps.php';
         }
 
         include_once($mapfile);
         $this->maps = $maps;  // $maps is set by included $mapfile
     }
-    
+
     public function getTrackingId()
-    {        
+    {
         if(isset($this->ectid)) return $this->ectid;
         else return '';
     }
 }
 
diff --git a/framework/modules/blog/controllers/blogController.php b/framework/modules/blog/controllers/blogController.php
index d2c6fa183e..9403aba9b5 100755
--- a/framework/modules/blog/controllers/blogController.php
+++ b/framework/modules/blog/controllers/blogController.php
@@ -191,11 +191,11 @@ class blogController extends expController {
 	public function show() {
         expHistory::set('viewable', $this->params);
 	    $id = isset($this->params['title']) ? $this->params['title'] : $this->params['id'];
         $record = new blog($id);
         if (empty($record->id))
-            redirect_to(array('controller'=>'notfound','action'=>'page_not_found','title'=>expString::escape($this->params['title'])));
+            redirect_to(array('controller'=>'notfound','action'=>'page_not_found','title'=>$this->params['title']));
 
 	    // since we are probably getting here via a router mapped url
 	    // some of the links (tags in particular) require a source, we will
 	    // populate the location data in the template now.
         $config = expConfig::getConfig($record->location_data);
diff --git a/framework/modules/search/controllers/searchController.php b/framework/modules/search/controllers/searchController.php
index 582a0f3858..47bceb426e 100755
--- a/framework/modules/search/controllers/searchController.php
+++ b/framework/modules/search/controllers/searchController.php
@@ -207,11 +207,11 @@ class searchController extends expController {
         ));
     }
 
     // some general search stuff
     public function autocomplete() {
-        return;
+        return;  //fixme this negates the code below!
         global $db;
 
         $model = $this->params['model'];
         $mod = new $model();
         $srchcol = explode(",",$this->params['searchoncol']);
@@ -229,11 +229,11 @@ class searchController extends expController {
 
         $ar = new expAjaxReply(200, gt('Here\'s the items you wanted'), $res);
         $ar->send();
     }
 
-	public function searchQueryReport() {
+	public function searchQueryReport() {  //fixme this will typically create a 500 error due to number of search query records
 		global $db;
 
 		//Instantiate the search model
 		$search = new search();
 
@@ -257,11 +257,11 @@ class searchController extends expController {
 
 		$ctr  = 2;
 		$ctr2 = 0;
 
 		//Getting the search users
-		$records = $db->selectObjects('search_queries');
+		$records = $db->selectObjects('search_queries');  // note we get all records a first time?
 
 
 		foreach($records as $item) {
 			$u = user::getUserById($item->user_id);
 
@@ -294,11 +294,11 @@ class searchController extends expController {
 			}
 			$where .= "user_id = {$u_id}";
 		}
 
 		//Get all the search query records
-		$records = $db->selectObjects('search_queries', $where);
+		$records = $db->selectObjects('search_queries', $where);  // note we then get all records a 2nd time?
         for ($i = 0, $iMax = count($records); $i < $iMax; $i++) {
 			if(!empty($records[$i]->user_id)) {
 				$u = user::getUserById($records[$i]->user_id);
 				$records[$i]->user = $u->firstname . ' ' . $u->lastname;
 			}
@@ -332,10 +332,11 @@ class searchController extends expController {
 
 	}
 
 	public function topSearchReport() {
 		global $db;
+
 		$limit = intval(TOP_SEARCH);
 
 		if(empty($limit)) {
 			$limit = 10;
 		}

Vulnerable code:     
    {           
        if(substr($fulllink, -1) == '/') $fulllink = substr($fulllink, 0, -1);  
        return $fulllink;                                   
    
                
        if (isset($params['section']) && $params['section'] == SITE_DEFAULT_SECTION) {            
            
            if (isset($params['section']) && !isset($params['action'])) {                
                }                               
            } else {                
                $link = '';               
        
            
                
                //trim last / off                 
                        }                    
                // if this url wasn't a valid section, or action then kill it.  It might not actually be a "bad" url, 
                if (!$ret) $this->url_type = 'malformed';  
            // if we hit this it's an old school url coming in and we're trying to use SEF's. 
            header("Location: ".$this->makeLink(array('section'=>intval($_REQUEST['section']))),TRUE,301);          
        if ($this->url_type != 'malformed') {               
            // if page or controller is not found we will route to the not found controller.            
            $this->url_parts = explode('/', $this->sefPath);     
            
                              
        define('PRINTER_FRIENDLY', (isset($_REQUEST['printerfriendly']) || isset($this->params['printerfriendly'])) ? 1 : 0);         
    public function routePageRequest() {        
                $_REQUEST['section'] = SITE_DEFAULT_SECTION;  
            // check the regular page names.  If that still doesn't work then we'll redirect them to the 
                    'url_parts'=>array(                
                    'url_parts'=>array(                
            //if section is empty, we'll look for the page overrides first and route to 
                $c = new storeCategory();                
                        //fake parts and route to action  
                        $this->url_type = 'action';                   
                        $this->url_parts[1] = 'show'; //controller
                        $this->url_parts[2] = 'title'; //controller
                        $this->url_parts[3] = $sef_url; //controller
                    //fake parts and route to action 
                    $this->url_type = 'action';                                      
                    $this->url_parts[1] = 'showall'; //controller
                    $this->url_parts[2] = 'title'; //controller                    
                    $this->url_parts[3] = $sef_url; //controller
        
            if ($part_count == count($map['url_parts'])) {               
                    } 
            }            
              
        
                
    
        }        
    
            // most of the time we can just grab the action outta the POST array since this is passed as a hidden field, 
    
    
        
        return $url; 
        
    
        
        $this->sefPath = substr($this->sefPath,strlen(substr(PATH_RELATIVE,0,-1))); 
        
                    $this->ectid = $s[1];    
                }   
            }            
                $section = $this->url_style=="sef" ? $this->getPageByName($_REQUEST['section'])->id : intval($_REQUEST['section']) ;
    
    
    
    {        
            redirect_to(array('controller'=>'notfound','action'=>'page_not_found','title'=>expString::escape($this->params['title'])));
        return;
	public function searchQueryReport() {
		$records = $db->selectObjects('search_queries');
		$records = $db->selectObjects('search_queries', $where);
Fixed code: 
    {
        if(substr($fulllink, -1) == '/') $fulllink = substr($fulllink, 0, -1);
        return $fulllink;


        if (isset($params['section']) && $params['section'] == SITE_DEFAULT_SECTION) {

            if (isset($params['section']) && !isset($params['action'])) {
                }
            } else {
                $link = '';



                //trim last / off
                        }
                // if this url wasn't a valid section, or action then kill it.  It might not actually be a "bad" url,
                if (!$ret) $this->url_type = 'malformed';
            // if we hit this it's an old school url coming in and we're trying to use SEF's.
            header("Location: ".$this->makeLink(array('section'=>intval($_REQUEST['section']))),TRUE,301);
        if ($this->url_type != 'malformed') {
            // if page or controller is not found we will route to the not found controller.
            $this->url_parts = explode('/', $this->sefPath);


        define('PRINTER_FRIENDLY', (isset($_REQUEST['printerfriendly']) || isset($this->params['printerfriendly'])) ? 1 : 0);
    public function routePageRequest() {
                $_REQUEST['section'] = SITE_DEFAULT_SECTION;
            // check the regular page names.  If that still doesn't work then we'll redirect them to the
                    'url_parts'=>array(
                    'url_parts'=>array(
            //if section is empty, we'll look for the page overrides first and route to
                $c = new storeCategory();
                        //fake parts and route to action
                        $this->url_type = 'action';
                        $this->url_parts[1] = 'show'; //action
                        $this->url_parts[2] = 'title'; //param name
                        $this->url_parts[3] = $sef_url; //param
                    //it's a store category
                    //fake parts and route to action
                    $this->url_type = 'action';
                    $this->url_parts[1] = 'showall'; //action
                    $this->url_parts[2] = 'title'; //param name
                    $this->url_parts[3] = $sef_url; //param
//fixme we may want to log missed pages (no existing store cat/product) requests and set up/use a redirect table (404)??
//fixme and we may also want to log any redirects taken??

            if ($part_count == count($map['url_parts'])) {
                    }
            }




        }

            // most of the time we can just grab the action outta the POST array since this is passed as a hidden field,



        return $url;



        $this->sefPath = substr($this->sefPath,strlen(substr(PATH_RELATIVE,0,-1)));

                    $this->ectid = $s[1];
                }
            }
                $section = $this->url_style=="sef" ? $this->getPageByName(expString::escape($_REQUEST['section']))->id : intval($_REQUEST['section']) ;



    {
            redirect_to(array('controller'=>'notfound','action'=>'page_not_found','title'=>$this->params['title']));
        return;  //fixme this negates the code below!
	public function searchQueryReport() {  //fixme this will typically create a 500 error due to number of search query records
		$records = $db->selectObjects('search_queries');  // note we get all records a first time?
		$records = $db->selectObjects('search_queries', $where);  // note we then get all records a 2nd time?