Vulnerability: SQL injection vulnerability in CPDB in application/controllers/admin/participantsaction.php in LimeSurvey 2.05+ Build 140618 allows remote attackers to execute arbitrary SQL commands via the sidx parameter in a JSON request to admin/participants/sa/getParticipants_json, related to a search parameter.
Vulnerability ID: CVE-2014-5017
CWE: CWE-89
Severity score: 6.4
Project: https://github.com/LimeSurvey/LimeSurvey
Published: 2014-07-21
File: application/controllers/admin/participantsaction.php
Commit message: Fixed issue: Search parameter vulnerability in CPDB
Commit author: Carsten Schmitz

Vulnerable version (before fix):
 function getParticipantsResults_json()     */     function getParticipants_json($search = null)     {         $page = Yii::app()->request->getPost('page');         $limit = Yii::app()->request->getPost('rows');         $limit = isset($limit) ? $limit : 50; //Stop division by zero errors          $attid = ParticipantAttributeName::model()->getVisibleAttributes();         $participantfields = array('participant_id', 'can_edit', 'firstname', 'lastname', 'email', 'blacklisted', 'survey', 'language', 'owner_uid'); function getParticipants_json($search = null)             array_push($participantfields, $value['attribute_id']);         }         $sidx = Yii::app()->request->getPost('sidx');         $sidx = !empty($sidx) ? $sidx : "lastname";         $sord = Yii::app()->request->getPost('sord');         $sord = !empty($sord) ? $sord : "asc";         $order = $sidx. " ". $sord;                  $aData = new stdClass;         

Fixed version (after fix):
 function getParticipantsResults_json()     */     function getParticipants_json($search = null)     {         $page = (int) Yii::app()->request->getPost('page');         $limit = (int) Yii::app()->request->getPost('rows');         $limit = empty($limit) ? $limit : 50; //Stop division by zero errors          $attid = ParticipantAttributeName::model()->getVisibleAttributes();         $participantfields = array('participant_id', 'can_edit', 'firstname', 'lastname', 'email', 'blacklisted', 'survey', 'language', 'owner_uid'); function getParticipants_json($search = null)             array_push($participantfields, $value['attribute_id']);         }         $sidx = Yii::app()->request->getPost('sidx');         $sidx = in_array($sidx,$participantfields) ? $sidx : "lastname";         $sord = Yii::app()->request->getPost('sord');         $sord = ($sord=='desc') ? 'desc' : 'asc';         $order = $sidx. " ". $sord;                                                                    $aData = new stdClass;         

Patch:
patch: @@ -763,9 +763,9 @@ function getParticipantsResults_json()
     */
     function getParticipants_json($search = null)
     {
-        $page = Yii::app()->request->getPost('page');
-        $limit = Yii::app()->request->getPost('rows');
-        $limit = isset($limit) ? $limit : 50; //Stop division by zero errors
+        $page = (int) Yii::app()->request->getPost('page');
+        $limit = (int) Yii::app()->request->getPost('rows');
+        $limit = empty($limit) ? $limit : 50; //Stop division by zero errors
 
         $attid = ParticipantAttributeName::model()->getVisibleAttributes();
         $participantfields = array('participant_id', 'can_edit', 'firstname', 'lastname', 'email', 'blacklisted', 'survey', 'language', 'owner_uid');
@@ -774,10 +774,11 @@ function getParticipants_json($search = null)
             array_push($participantfields, $value['attribute_id']);
         }
         $sidx = Yii::app()->request->getPost('sidx');
-        $sidx = !empty($sidx) ? $sidx : "lastname";
+        $sidx = in_array($sidx,$participantfields) ? $sidx : "lastname";
         $sord = Yii::app()->request->getPost('sord');
-        $sord = !empty($sord) ? $sord : "asc";
+        $sord = ($sord=='desc') ? 'desc' : 'asc';
         $order = $sidx. " ". $sord;
+                                                 
         
         $aData = new stdClass;
path: application/controllers/admin/participantsaction.php