Skip to content

Commit

Permalink
Fixed several SQL injection leaks in the controllers
Browse files Browse the repository at this point in the history
git-svn-id: file:///Users/Shitiz/Downloads/lssvn/source/limesurvey_yii@12058 b72ed6b6-b9f8-46b5-92b4-906544132732
  • Loading branch information
Daniel Klischies committed Jan 14, 2012
1 parent 3fd6ddc commit 61e2716
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 78 deletions.
4 changes: 2 additions & 2 deletions application/controllers/InstallerController.php
Expand Up @@ -804,11 +804,11 @@ function _setup_tables($sFileName, $aDbConfig = array(), $sDatabasePrefix = '')
switch ($sDatabaseType) {
case 'mysql':
case 'mysqli':
$this->connection->createCommand("ALTER DATABASE `{$sDatabaseName}` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;")->execute();
$this->connection->createCommand("ALTER DATABASE ". Yii::app()->db->quoteTableName($sDatabaseName) ." DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;")->execute();
break;
case 'pgsql':
if ($this->connection->getClientVersion() == '9') {
$this->connection->createCommand("ALTER DATABASE {$sDatabaseName} SET bytea_output='escape';")->execute();
$this->connection->createCommand("ALTER DATABASE ". Yii::app()->db->quoteTableName($sDatabaseName) ." SET bytea_output='escape';")->execute();
}
break;
}
Expand Down
32 changes: 16 additions & 16 deletions application/controllers/Statistics_userController.php
Expand Up @@ -185,7 +185,7 @@ function actionAction($surveyid)
* only show questions where question attribute "public_statistics" is set to "1"
*/

$query = "SELECT q.* , group_name, group_order FROM {{questions}} q, {{groups}} g, {{question_attributes}} qa WHERE 'g.gid' = 'q.gid' AND 'g.language' = '".$language."' AND 'q.language' = '".$language."' AND 'q.sid' = {$surveyid} AND 'q.qid' = 'qa.qid' AND 'q.parent_qid' = 0 AND 'qa.attribute' = 'public_statistics'";
$query = "SELECT q.* , group_name, group_order FROM {{questions}} q, {{groups}} g, {{question_attributes}} qa WHERE 'g.gid' = 'q.gid' AND 'g.language' = :lang AND 'q.language' = :lang AND 'q.sid' = :surveyid AND 'q.qid' = 'qa.qid' AND 'q.parent_qid' = 0 AND 'qa.attribute' = 'public_statistics'";
$databasetype = Yii::app()->db->getDriverName();
if ($databasetype=='mssql_n' or $databasetype=='mssql' or $databasetype=='odbc_mssql' or $databasetype=="mssqlnative")
{
Expand All @@ -197,7 +197,7 @@ function actionAction($surveyid)
}

//execute query
$result = Yii::app()->db->createCommand($query)->queryAll();
$result = Yii::app()->db->createCommand($query)->bindParam(":lang", $language, PDO::PARAM_STR)->bindParam(":surveyid", $surveyid, PDO::PARAM_INT)->queryAll();

//store all the data in $rows
$rows = $result;
Expand All @@ -222,13 +222,13 @@ function actionAction($surveyid)
$totalrecords = 0;

//count number of answers
$query = "SELECT count(*) FROM {{survey_$surveyid}}";
$query = "SELECT count(*) FROM {{survey_{intval($surveyid)}}}";

//if incompleted answers should be filtert submitdate has to be not null
//this setting is taken from config-defaults.php
if (Yii::app()->getConfig("filterout_incomplete_answers") == true)
{
$query .= " WHERE {{survey_$surveyid}}.submitdate is not null";
$query .= " WHERE {{survey_{intval($surveyid)}}}.submitdate is not null";
}
$result = Yii::app()->db->createCommand($query)->queryAll();

Expand Down Expand Up @@ -271,8 +271,8 @@ function actionAction($surveyid)
case "K": // Multiple Numerical
case "Q": // Multiple Short Text
//get answers
$query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid='$flt[0]' AND language = '{$language}' ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->queryAll();
$query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid=:flt_0 AND language = :lang ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":flt_0", $language, PDO::PARAM_STR)->queryAll();

//go through all the (multiple) answers
foreach($result as $row)
Expand All @@ -288,8 +288,8 @@ function actionAction($surveyid)
case "F": // FlEXIBLE ARRAY
case "H": // ARRAY (By Column)
//get answers
$query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid='$flt[0]' AND language = '{$language}' ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->queryAll();
$query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid=:flt_0 AND language = :lang ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":flt_0", $language, PDO::PARAM_STR)->queryAll();

//go through all the (multiple) answers
foreach($result as $row)
Expand All @@ -307,12 +307,12 @@ function actionAction($surveyid)
break;
case ";": //ARRAY (Multi Flex) (Text)
case ":": //ARRAY (Multi Flex) (Numbers)
$query = "SELECT title, question FROM {{questions}} WHERE parent_qid='$flt[0]' AND language='{$language}' AND scale_id = 0 ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->queryAll();
$query = "SELECT title, question FROM {{questions}} WHERE parent_qid=:flt_0 AND language=:lang AND scale_id = 0 ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":flt_0", $language, PDO::PARAM_STR)->queryAll();
foreach($result as $row)
{
$fquery = "SELECT * FROM {{questions}} WHERE parent_qid = {$flt[0]} AND language = '{$language}' AND scale_id = 1 ORDER BY question_order, title";
$fresult = Yii::app()->db->createCommand($query)->queryAll();
$fquery = "SELECT * FROM {{questions}} WHERE parent_qid = :flt_0 AND language = :lang AND scale_id = 1 ORDER BY question_order, title";
$fresult = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":flt_0", $language, PDO::PARAM_STR)->queryAll();
foreach($fresult as $frow)
{
$myfield2 = $myfield . reset($row) . "_" . $frow['title'];
Expand All @@ -322,8 +322,8 @@ function actionAction($surveyid)
break;
case "R": //RANKING
//get some answers
$query = "SELECT code, answer FROM {{answers}} WHERE qid = '$flt[0]' AND language = '{$language}' ORDER BY sortorder, answer";
$result = Yii::app()->db->createCommand($query)->queryAll();
$query = "SELECT code, answer FROM {{answers}} WHERE qid = :flt_0 AND language = :lang ORDER BY sortorder, answer";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":flt_0", $language, PDO::PARAM_STR)->queryAll();

//get number of answers
$count = $result->num_rows();
Expand All @@ -340,8 +340,8 @@ function actionAction($surveyid)
break;
case "1": // MULTI SCALE
//get answers
$query = "SELECT title, question FROM {{questions}} WHERE parent_qid = '$flt[0]' AND language = '{$language}' ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->queryAll();
$query = "SELECT title, question FROM {{questions}} WHERE parent_qid = :flt_0 AND language = :lang ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":flt_0", $language, PDO::PARAM_STR)->queryAll();

//loop through answers
foreach($result as $row)
Expand Down
68 changes: 35 additions & 33 deletions application/controllers/admin/conditionsaction.php
Expand Up @@ -400,8 +400,8 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
// RENUMBER SCENARIOS
if (isset($p_subaction) && $p_subaction == "renumberscenarios")
{
$query = "SELECT DISTINCT scenario FROM {{conditions}} WHERE qid={$qid} ORDER BY scenario";
$result = Yii::app()->db->createCommand($query)->query() or safe_die ("Couldn't select scenario<br />$query<br />");
$query = "SELECT DISTINCT scenario FROM {{conditions}} WHERE qid=:qid ORDER BY scenario";
$result = Yii::app()->db->createCommand($query)->bindParam(":qid", $qid, PDO::PARAM_INT)->query() or safe_die ("Couldn't select scenario<br />$query<br />");
$newindex = 1;

foreach ($result->readAll() as $srow)
Expand All @@ -426,9 +426,11 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
if (isset($copyconditionsto) && is_array($copyconditionsto) && isset($copyconditionsfrom) && is_array($copyconditionsfrom))
{
//Get the conditions we are going to copy
foreach($copyconditionsfrom as &$entry)
$entry = Yii::app()->db->quoteValue($entry);
$query = "SELECT * FROM {{conditions}}\n"
."WHERE cid in ('";
$query .= implode("', '", $copyconditionsfrom);
$query .= implode(", ", $copyconditionsfrom);
$query .= "')";
$result = Yii::app()->db->createCommand($query)->query() or
safe_die("Couldn't get conditions for copy<br />$query<br />");
Expand Down Expand Up @@ -524,10 +526,10 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
."FROM {{questions}}, "
."{{groups}} "
."WHERE {{questions}}.gid={{groups}}.gid "
."AND qid=$qid "
."AND qid=:qid "
."AND parent_qid=0 "
."AND {{questions}}.language='".Survey::model()->findByPk($surveyid)->language."'";
$result = Yii::app()->db->createCommand($query)->query() or safe_die ("Couldn't get information for question $qid<br />$query<br />");
."AND {{questions}}.language=:lang";
$result = Yii::app()->db->createCommand($query)->bindParam(":qid", $qid, PDO::PARAM_INT)->bindParam(":lang", Survey::model()->findByPk($surveyid)->language, PDO::PARAM_STR)->query() or safe_die ("Couldn't get information for question $qid<br />$query<br />");
foreach ($result->readAll() as $rows)
{
$questiongroupname = $rows['group_name'];
Expand All @@ -547,10 +549,10 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
."WHERE {{questions}}.gid={{groups}}.gid "
."AND parent_qid=0 "
."AND {{questions}}.sid=$surveyid "
."AND {{questions}}.language='".Survey::model()->findByPk($surveyid)->language."' "
."AND {{groups}}.language='".Survey::model()->findByPk($surveyid)->language."' " ;
."AND {{questions}}.language=:lang "
."AND {{groups}}.language=:lang " ;

$qresult = Yii::app()->db->createCommand($qquery)->query() or safe_die ("$qquery<br />");
$qresult = Yii::app()->db->createCommand($qquery)->bindParam(":lang", Survey::model()->findByPk($surveyid)->language, PDO::PARAM_STR)->query() or safe_die ("$qquery<br />");
$qrows = $qresult->readAll();
// Perform a case insensitive natural sort on group name then question title (known as "code" in the form) of a multidimensional array
usort($qrows, 'GroupOrderThenQuestionOrder');
Expand Down Expand Up @@ -607,10 +609,10 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
."WHERE {{questions}}.gid={{groups}}.gid "
."AND parent_qid=0 "
."AND {{questions}}.qid=$ql "
."AND {{questions}}.language='".Survey::model()->findByPk($surveyid)->language."' "
."AND {{groups}}.language='".Survey::model()->findByPk($surveyid)->language."'" ;
."AND {{questions}}.language=:lang"
."AND {{groups}}.language=:lang" ;

$result = Yii::app()->db->createCommand($query)->query() or die("Couldn't get question $qid");
$result = Yii::app()->db->createCommand($query)->bindParam(":lang", Survey::model()->findByPk($surveyid)->language, PDO::PARAM_STR)->query() or die("Couldn't get question $qid");

$thiscount = count($result);

Expand Down Expand Up @@ -648,11 +650,11 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
."WHERE q.gid=g.gid AND "
."q.parent_qid=0 AND "
."q.qid=$pq AND "
."q.language='".Survey::model()->findByPk($surveyid)->language."' AND "
."g.language='".Survey::model()->findByPk($surveyid)->language."'";
."q.language=:lang AND "
."g.language=:lang";


$result = Yii::app()->db->createCommand($query)->query() or safe_die("Couldn't get postquestions $qid<br />$query<br />");
$result = Yii::app()->db->createCommand($query)->bindParam(":lang", Survey::model()->findByPk($surveyid)->language, PDO::PARAM_STR)->query() or safe_die("Couldn't get postquestions $qid<br />$query<br />");

$postcount = count($result);

Expand Down Expand Up @@ -789,26 +791,26 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
$fquery = "SELECT sq.*, q.other"
." FROM {{questions sq}}, {{questions q}}"
." WHERE sq.sid=$surveyid AND sq.parent_qid=q.qid "
. "AND q.language='".Survey::model()->findByPk($surveyid)->language."'"
." AND sq.language='".Survey::model()->findByPk($surveyid)->language."'"
." AND q.qid={$rows['qid']}
. "AND q.language=:lang"
." AND sq.language=:lang"
." AND q.qid=:qid
AND sq.scale_id=0
ORDER BY sq.question_order";

$y_axis_db = Yii::app()->db->createCommand($fquery)->query();
$y_axis_db = Yii::app()->db->createCommand($fquery)->bindParam(":lang", Survey::model()->findByPk($surveyid)->language, PDO::PARAM_STR)->bindParam(":qid", $rows["qid"], PDO::PARAM_INT)->query();

// Get the X-Axis
$aquery = "SELECT sq.*
FROM {{questions q}}, {{questions sq}}
WHERE q.sid=$surveyid
AND sq.parent_qid=q.qid
AND q.language='".Survey::model()->findByPk($surveyid)->language."'
AND sq.language='".Survey::model()->findByPk($surveyid)->language."'
AND q.qid=".$rows['qid']."
AND q.language=:lang
AND sq.language=:lang
AND q.qid=:qid
AND sq.scale_id=1
ORDER BY sq.question_order";

$x_axis_db=Yii::app()->db->createCommand($aquery)->query() or safe_die ("Couldn't get answers to Array questions<br />$aquery<br />");
$x_axis_db=Yii::app()->db->createCommand($aquery)->bindParam(":lang", Survey::model()->findByPk($surveyid)->language, PDO::PARAM_STR)->bindParam(":qid", $rows[qid], PDO::PARAM_INT)->query() or safe_die ("Couldn't get answers to Array questions<br />$aquery<br />");

foreach ($x_axis_db->readAll() as $frow)
{
Expand Down Expand Up @@ -1192,9 +1194,9 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
$s=0;
$scenarioquery = "SELECT DISTINCT {{conditions}}.scenario "
."FROM {{conditions}} "
."WHERE {{conditions}}.qid=$qid\n"
."WHERE {{conditions}}.qid=:qid"
."ORDER BY {{conditions}}.scenario";
$scenarioresult = Yii::app()->db->createCommand($scenarioquery)->query() or safe_die ("Couldn't get other (scenario) conditions for question $qid<br />$query<br />");
$scenarioresult = Yii::app()->db->createCommand($scenarioquery)->bindParam(":qid", $qid, PDO::PARAM_INT)->query() or safe_die ("Couldn't get other (scenario) conditions for question $qid<br />$query<br />");
$scenariocount=count($scenarioresult);

$showreplace="$questiontitle". $this->_showSpeaker($questiontext);
Expand Down Expand Up @@ -1286,13 +1288,13 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
."WHERE {{conditions}}.cqid={{questions}}.qid "
."AND {{questions}}.gid={{groups}}.gid "
."AND {{questions}}.parent_qid=0 "
."AND {{questions}}.language='".Survey::model()->findByPk($surveyid)->language."' "
."AND {{groups}}.language='".Survey::model()->findByPk($surveyid)->language."' "
."AND {{conditions}}.qid=$qid "
."AND {{conditions}}.scenario={$scenarionr['scenario']}\n"
."AND {{questions}}.language=:lang "
."AND {{groups}}.language=:lang "
."AND {{conditions}}.qid=:qid "
."AND {{conditions}}.scenario=:scenario"
."AND {{conditions}}.cfieldname NOT LIKE '{%' \n" // avoid catching SRCtokenAttr conditions
."ORDER BY {{groups}}.group_order,{{questions}}.question_order";
$result = Yii::app()->db->createCommand($query)->query() or safe_die ("Couldn't get other conditions for question $qid<br />$query<br />");
$result = Yii::app()->db->createCommand($query)->bindParam(":scenario", $scenarionr['scenario'], PDO::PARAM_INT)->bindParam(":qid", $qid, PDO::PARAM_INT)->bindParam(":lang", Survey::model()->findByPk($surveyid)->language, PDO::PARAM_STR)->query() or safe_die ("Couldn't get other conditions for question $qid<br />$query<br />");
$conditionscount=count($result);

$querytoken = "SELECT {{conditions}}.cid, "
Expand All @@ -1304,11 +1306,11 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null)
."'' AS type "
."FROM {{conditions}} "
."WHERE "
." {{conditions}}.qid=$qid "
."AND {{conditions}}.scenario={$scenarionr['scenario']}\n"
." {{conditions}}.qid=:qid "
."AND {{conditions}}.scenario=:scenario\n"
."AND {{conditions}}.cfieldname LIKE '{%' \n" // only catching SRCtokenAttr conditions
."ORDER BY {{conditions}}.cfieldname";
$resulttoken = Yii::app()->db->createCommand($querytoken)->query() or safe_die ("Couldn't get other conditions for question $qid<br />$query<br />");
$resulttoken = Yii::app()->db->createCommand($querytoken)->bindParam(":scenario", $scenarionr['scenario'], PDO::PARAM_INT)->bindParam(":qid", $qid, PDO::PARAM_INT)->query() or safe_die ("Couldn't get other conditions for question $qid<br />$query<br />");
$conditionscounttoken=count($resulttoken);

$conditionscount=$conditionscount+$conditionscounttoken;
Expand Down
7 changes: 6 additions & 1 deletion application/controllers/admin/dataentry.php
Expand Up @@ -1799,7 +1799,12 @@ public function insert()
}

$surveytable = "{{survey_{$surveyid}}}";


foreach($columns as &$colrow)
$colrow = Yii::app()->db->quoteColumnName($colrow);
foreach($values as &$valrow)
$valrow = Yii::app()->db->quoteValue($valrow);

$SQL = "INSERT INTO $surveytable
(".implode(',', $columns).")
VALUES
Expand Down

0 comments on commit 61e2716

Please sign in to comment.