CVE-2016-9242: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: Multiple SQL injection vulnerabilities in the update method in framework/modules/core/controllers/expRatingController.php in Exponent CMS 2.4.0 allow remote authenticated users to execute arbitrary SQL commands via the (1) content_type or (2) subtype 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: 8.8
Published: 2016-11-07T11:59Z
Repository: https://github.com/exponentcms/exponent-cms
Language: PHP
Files changed: framework/modules/core/controllers/expRatingController.php
Commit date: 2016-11-03 11:00:13 -0400
Commit message: fix security vulnerability in ratings; reported by fyth

Diff: diff --git a/framework/modules/core/controllers/expRatingController.php b/framework/modules/core/controllers/expRatingController.php
index be4bb222b90..7090008407d 100644
--- a/framework/modules/core/controllers/expRatingController.php
+++ b/framework/modules/core/controllers/expRatingController.php
@@ -26,11 +26,11 @@ class expRatingController extends expController {
     public $base_class = 'expRating';
 
     static function displayname() { return gt("Ratings Manager"); }
     static function description() { return gt("This module is for managing ratings on records"); }
     static function hasSources() { return false; }
-	
+
 	function __construct($src=null, $params=array()) {
         global $user;
 	    parent::__construct($src, $params);
         $this->remove_permissions = ($user->isLoggedIn())?array('update','create'):array();
     }
@@ -38,11 +38,13 @@ class expRatingController extends expController {
     /**
      * Update rating...handled via ajax
      */
     function update() {
         global $db, $user;
-        	
+
+        $this->params['content_type'] = preg_replace("/[^[:alnum:][:space:]]/u", '', $this->params['content_type']);
+        $this->params['subtype'] = preg_replace("/[^[:alnum:][:space:]]/u", '', $this->params['subtype']);
         $this->params['id'] = $db->selectValue('content_expRatings','expratings_id',"content_id='".$this->params['content_id']."' AND content_type='".$this->params['content_type']."' AND subtype='".$this->params['subtype']."' AND poster='".$user->id."'");
         $msg = gt('Thank you for your rating');
         $rating = new expRating($this->params);
         if (!empty($rating->id)) $msg = gt('Your rating has been adjusted');
         // save the rating
@@ -57,13 +59,13 @@ class expRatingController extends expController {
 		if(isset($this->params['subtype'])) $obj->subtype = $this->params['subtype'];
 		$db->insertObject($obj, $rating->attachable_table);
 
         $ar = new expAjaxReply(200,$msg);
         $ar->send();
-		
+
         // flash('message', $msg);
         // expHistory::back();
 	}
-	
+
 }
 
 ?>
\ No newline at end of file

Fixed code: 

        $this->params['content_type'] = preg_replace("/[^[:alnum:][:space:]]/u", '', $this->params['content_type']);
        $this->params['subtype'] = preg_replace("/[^[:alnum:][:space:]]/u", '', $this->params['subtype']);