Skip to content

Commit e916702

Browse files
committed
security fix several sql injection vulnerabilities reported by Manuel Garcia Cardenas and PKAV TEAM
1 parent 26cdc39 commit e916702

File tree

5 files changed

+75
-33
lines changed

5 files changed

+75
-33
lines changed

Diff for: framework/core/subsystems/database/mysqli.php

+18-7
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,8 @@ function columnUpdate($table, $col, $val, $where=1) {
379379
function selectObjects($table, $where = null, $orderby = null) {
380380
if ($where == null)
381381
$where = "1";
382+
else
383+
$where = $this->injectProof($where);
382384
if ($orderby == null)
383385
$orderby = '';
384386
else
@@ -484,7 +486,7 @@ function selectObjectBySql($sql) {
484486
//$lfh = fopen($logFile, 'a');
485487
//fwrite($lfh, $sql . "\n");
486488
//fclose($lfh);
487-
$res = @mysqli_query($this->connection, $sql);
489+
$res = @mysqli_query($this->connection, $this->injectProof($sql));
488490
if ($res == null)
489491
return null;
490492
return mysqli_fetch_object($res);
@@ -497,7 +499,7 @@ function selectObjectBySql($sql) {
497499
* @return array
498500
*/
499501
function selectObjectsBySql($sql) {
500-
$res = @mysqli_query($this->connection, $sql);
502+
$res = @mysqli_query($this->connection, $this->injectProof($sql));
501503
if ($res == null)
502504
return array();
503505
$objects = array();
@@ -638,6 +640,8 @@ function selectValueBySql($sql) {
638640
function selectObjectsIndexedArray($table, $where = null, $orderby = null) {
639641
if ($where == null)
640642
$where = "1";
643+
else
644+
$where = $this->injectProof($where);
641645
if ($orderby == null)
642646
$orderby = '';
643647
else
@@ -722,6 +726,7 @@ function queryRows($sql) {
722726
* @return object/null|void
723727
*/
724728
function selectObject($table, $where) {
729+
$where = $this->injectProof($where);
725730
$res = mysqli_query($this->connection, "SELECT * FROM `" . $this->prefix . "$table` WHERE $where LIMIT 0,1");
726731
if ($res == null)
727732
return null;
@@ -773,7 +778,7 @@ function insertObject($object, $table) {
773778
if ($values != ") VALUES (") {
774779
$values .= ",";
775780
}
776-
$values .= "'" . mysqli_real_escape_string($this->connection, $val) . "'";
781+
$values .= "'" . $this->escapeString($val) . "'";
777782
}
778783
}
779784
$sql = substr($sql, 0, -1) . substr($values, 0) . ")";
@@ -836,13 +841,13 @@ function updateObject($object, $table, $where=null, $identifier='id', $is_revisi
836841
$val = serialize($val);
837842
$sql .= "`$var`='".$val."',";
838843
} else {
839-
$sql .= "`$var`='".mysqli_real_escape_string($this->connection,$val)."',";
844+
$sql .= "`$var`='" . $this->escapeString($val) . "',";
840845
}
841846
}
842847
}
843848
$sql = substr($sql, 0, -1) . " WHERE ";
844849
if ($where != null)
845-
$sql .= $where;
850+
$sql .= $this->injectProof($where);
846851
else
847852
$sql .= "`" . $identifier . "`=" . $object->$identifier;
848853
//if ($table == 'text') eDebug($sql,true);
@@ -1130,6 +1135,8 @@ function escapeString($string) {
11301135
function selectArrays($table, $where = null, $orderby = null) {
11311136
if ($where == null)
11321137
$where = "1";
1138+
else
1139+
$where = $this->injectProof($where);
11331140
if ($orderby == null)
11341141
$orderby = '';
11351142
else
@@ -1156,7 +1163,7 @@ function selectArrays($table, $where = null, $orderby = null) {
11561163
* @return array
11571164
*/
11581165
function selectArraysBySql($sql) {
1159-
$res = @mysqli_query($this->connection, $sql);
1166+
$res = @mysqli_query($this->connection, $this->injectProof($sql));
11601167
if ($res == null)
11611168
return array();
11621169
$arrays = array();
@@ -1185,6 +1192,8 @@ function selectArraysBySql($sql) {
11851192
function selectArray($table, $where = null, $orderby = null, $is_revisioned=false, $needs_approval=false) {
11861193
if ($where == null)
11871194
$where = "1";
1195+
else
1196+
$where = $this->injectProof($where);
11881197
$as = '';
11891198
if ($is_revisioned) {
11901199
// $where.= " AND revision_id=(SELECT MAX(revision_id) FROM `" . $this->prefix . "$table` WHERE $where)";
@@ -1223,6 +1232,8 @@ function selectArray($table, $where = null, $orderby = null, $is_revisioned=fals
12231232
function selectExpObjects($table, $where=null, $classname, $get_assoc=true, $get_attached=true, $except=array(), $cascade_except=false, $order=null, $limitsql=null, $is_revisioned=false, $needs_approval=false) {
12241233
if ($where == null)
12251234
$where = "1";
1235+
else
1236+
$where = $this->injectProof($where);
12261237
$as = '';
12271238
if ($is_revisioned) {
12281239
// $where.= " AND revision_id=(SELECT MAX(revision_id) FROM `" . $this->prefix . "$table` WHERE $where)";
@@ -1259,7 +1270,7 @@ function selectExpObjects($table, $where=null, $classname, $get_assoc=true, $get
12591270
* @return array
12601271
*/
12611272
function selectExpObjectsBySql($sql, $classname, $get_assoc=true, $get_attached=true) {
1262-
$res = @mysqli_query($this->connection, $sql);
1273+
$res = @mysqli_query($this->connection, $this->injectProof($sql));
12631274
if ($res == null)
12641275
return array();
12651276
$arrays = array();

Diff for: framework/core/subsystems/expDatabase.php

+15
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,21 @@ abstract function inError();
11051105
*/
11061106
abstract function escapeString($string);
11071107

1108+
/**
1109+
* Unescape a string based on the database connection
1110+
* @param $string
1111+
* @return string
1112+
*/
1113+
function injectProof($string) {
1114+
$quotes = substr_count("'", $string);
1115+
if ($quotes % 2 != 0)
1116+
$string = $this->escapeString($string);
1117+
$dquotes = substr_count('"', $string);
1118+
if ($dquotes % 2 != 0)
1119+
$string = $this->escapeString($string);
1120+
return $string;
1121+
}
1122+
11081123
/**
11091124
* Create a SQL "limit" phrase
11101125
*

Diff for: framework/core/subsystems/expRouter.php

+22-7
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,26 @@ public function routeRequest() {
198198
);
199199
}
200200
}
201-
// conventional method to ensure the 'id' is an id
202-
if (isset($_GET['id'])) {
203-
$_GET['id'] = intval($_GET['id']);
201+
// conventional method to ensure the 'id' is only an id
202+
if (isset($_REQUEST['id'])) {
203+
if (isset($_GET['id']))
204+
$_GET['id'] = intval($_GET['id']);
205+
if (isset($_POST['id']))
206+
$_POST['id'] = intval($_POST['id']);
207+
204208
$_REQUEST['id'] = intval($_REQUEST['id']);
205209
}
210+
// do the same for the other id's
211+
foreach ($_REQUEST as $key=>$var) {
212+
if (is_string($var) && strrpos($key,'_id',-3) !== false) {
213+
if (isset($_GET[$key]))
214+
$_GET[$key] = intval($_GET[$key]);
215+
if (isset($_POST[$key]))
216+
$_POST[$key] = intval($_POST[$key]);
217+
218+
$_REQUEST[$key] = intval($_REQUEST[$key]);
219+
}
220+
}
206221
if (empty($user->id) || (!empty($user->id) && !$user->isAdmin())) { //FIXME why would $user be empty here unless $db is down?
207222
// $_REQUEST['route_sanitized'] = true;//FIXME debug test
208223
expString::sanitize($_REQUEST); // strip other exploits like sql injections
@@ -307,14 +322,14 @@ public function splitURL() {
307322

308323
if (count($this->url_parts) < 1 || (empty($this->url_parts[0]) && count($this->url_parts) == 1) ) {
309324
$this->url_type = 'base'; // no params
310-
} elseif (count($this->url_parts) == 1 || $db->selectObject('section', "sef_name='" . substr($db->escapeString($this->sefPath),1) . "'") != null) {
325+
} elseif (count($this->url_parts) == 1 || $db->selectObject('section', "sef_name='" . substr($this->sefPath,1) . "'") != null) {
311326
$this->url_type = 'page'; // single param is page name
312327
} elseif ($_SERVER['REQUEST_METHOD'] == 'POST') {
313328
$this->url_type = 'post'; // params via form/post
314329
} else {
315330
// take a peek and see if a page exists with the same name as the first value...if so we probably have a page with
316331
// extra perms...like printerfriendly=1 or ajax_action=1;
317-
if (($db->selectObject('section', "sef_name='" . $db->escapeString($this->url_parts[0]) . "'") != null) && (in_array(array('printerfriendly','exportaspdf','ajax_action'), $this->url_parts))) {
332+
if (($db->selectObject('section', "sef_name='" . $this->url_parts[0] . "'") != null) && (in_array(array('printerfriendly','exportaspdf','ajax_action'), $this->url_parts))) {
318333
$this->url_type = 'page';
319334
} else {
320335
$this->url_type = 'action';
@@ -547,7 +562,7 @@ public function buildCurrentUrl() {
547562
} else {
548563
$url .= urldecode((empty($_SERVER['REQUEST_URI'])) ? $_ENV['REQUEST_URI'] : $_SERVER['REQUEST_URI']);
549564
}
550-
return expString::sanitize($url);
565+
return expString::escape(expString::sanitize($url));
551566
}
552567

553568
public static function encode($url) {
@@ -760,7 +775,7 @@ private function buildSEFPath () {
760775
if (substr($this->sefPath,-1) == "/") $this->sefPath = substr($this->sefPath,0,-1);
761776
// sanitize it
762777
$sefPath = explode('">',$this->sefPath); // remove any attempts to close the command
763-
$this->sefPath = expString::sanitize($sefPath[0]);
778+
$this->sefPath = expString::escape(expString::sanitize($sefPath[0]));
764779
}
765780

766781
public function getSection() {

Diff for: framework/core/subsystems/expString.php

+17-17
Original file line numberDiff line numberDiff line change
@@ -522,23 +522,23 @@ public static function sanitize(&$data) {
522522
$data = self::xss_clean($data);
523523

524524
//fixme orig exp method
525-
if(0) {
526-
// remove whitespaces and tags
527-
// $data = strip_tags(trim($data));
528-
// remove whitespaces and script tags
529-
$data = self::strip_tags_content(trim($data), '<script>', true);
530-
// $data = self::strip_tags_content(trim($data), '<iframe>', true);
531-
532-
// apply stripslashes if magic_quotes_gpc is enabled
533-
if (get_magic_quotes_gpc()) {
534-
$data = stripslashes($data);
535-
}
536-
537-
$data = self::escape($data);
538-
539-
// re-escape newlines
540-
$data = str_replace(array('\r', '\n'), array("\r", "\n"), $data);
541-
}
525+
// if(0) {
526+
// // remove whitespaces and tags
527+
//// $data = strip_tags(trim($data));
528+
// // remove whitespaces and script tags
529+
// $data = self::strip_tags_content(trim($data), '<script>', true);
530+
//// $data = self::strip_tags_content(trim($data), '<iframe>', true);
531+
//
532+
// // apply stripslashes if magic_quotes_gpc is enabled
533+
// if (get_magic_quotes_gpc()) {
534+
// $data = stripslashes($data);
535+
// }
536+
//
537+
// $data = self::escape($data);
538+
//
539+
// // re-escape newlines
540+
// $data = str_replace(array('\r', '\n'), array("\r", "\n"), $data);
541+
// }
542542
}
543543
return $data;
544544
}

Diff for: framework/core/subsystems/expTheme.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ public static function runAction()
762762
if (!$user->isAdmin())
763763
expString::sanitize($_REQUEST);
764764
// } elseif (empty($_REQUEST['array_sanitized'])) {
765-
$tmp =1; //FIXME we've already sanitized at this point
765+
// $tmp =1; //FIXME we've already sanitized at this point
766766
// } else {
767767
// $tmp =1; //FIXME we've already sanitized at this point
768768
// }
@@ -843,7 +843,8 @@ public static function showAction($module, $action, $src = "", $params = array()
843843
//// $_GET[$key] = $value;
844844
// $_GET[$key] = expString::sanitize($value);
845845
// }
846-
if (!$user->isAdmin()) expString::sanitize($_GET);
846+
if (!$user->isAdmin())
847+
expString::sanitize($_GET);
847848
}
848849
//if (isset($['_common'])) $actfile = "/common/actions/" . $_REQUEST['action'] . ".php";
849850

0 commit comments

Comments
 (0)