Vulnerability: 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.
Vulnerability ID: CVE-2016-9242
CWE: CWE-89
Severity score: 6.4
Project: https://github.com/exponentcms/exponent-cms
Published: 2016-11-07
File: framework/modules/core/controllers/expRatingController.php
Commit message: fix security vulnerability in ratings; reported by fyth
Commit author: dleffler

Vulnerable version (before fix):
 class expRatingController extends expController {     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); function __construct($src=null, $params=array()) {      */     function update() {         global $db, $user;         	         $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); function update() {          $ar = new expAjaxReply(200,$msg);         $ar->send(); 		         // flash('message', $msg);         // expHistory::back(); 	} 	 }  ?>\ No newline at end of file

Fixed version (after fix):
 class expRatingController extends expController {     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); function __construct($src=null, $params=array()) {      */     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); function update() {          $ar = new expAjaxReply(200,$msg);         $ar->send();          // flash('message', $msg);         // expHistory::back(); 	}  }  ?>\ No newline at end of file

Patch:
patch: @@ -28,7 +28,7 @@ class expRatingController extends expController {
     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);
@@ -40,7 +40,9 @@ function __construct($src=null, $params=array()) {
      */
     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);
@@ -59,11 +61,11 @@ function update() {
 
         $ar = new expAjaxReply(200,$msg);
         $ar->send();
-		
+
         // flash('message', $msg);
         // expHistory::back();
 	}
-	
+
 }
 
 ?>
\ No newline at end of file
path: framework/modules/core/controllers/expRatingController.php