Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.

Commit

Permalink
fix(secu): Avoid SQL injections in service by servicegroup pages (#8065)
Browse files Browse the repository at this point in the history
* fix(secu): avoid SQL injection in serviceByServicegroupGridXML.php file
* fix(secu): avoid SQL injection in serviceByServicegroupSummaryXML.php file
* fix(secu): remove or sanitize unused https arguments in service by servicegroup GRID (#8066)
  • Loading branch information
sc979 committed Nov 12, 2019
1 parent 3fa6e29 commit 0ee8451
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,15 @@

ini_set("display_errors", "Off");

require_once realpath(__DIR__ . "/../../../../../../config/centreon.config.php");
require_once realpath(__DIR__ . "/../../../../../../bootstrap.php");

include_once _CENTREON_PATH_ . "www/class/centreonUtils.class.php";

include_once _CENTREON_PATH_ . "www/class/centreonXMLBGRequest.class.php";
include_once _CENTREON_PATH_ . "www/include/monitoring/status/Common/common-Func.php";
include_once _CENTREON_PATH_ . "www/include/common/common-Func.php";
include_once _CENTREON_PATH_ . "www/class/centreonService.class.php";

// Create XML Request Objects
CentreonSession::start();
CentreonSession::start();
$obj = new CentreonXMLBGRequest($dependencyInjector, session_id(), 1, 1, 0, 1);
$svcObj = new CentreonService($obj->DB);

Expand All @@ -59,19 +56,30 @@
$obj->getDefaultFilters();

// Check Arguments From GET tab
$o = $obj->checkArgument("o", $_GET, "h");
$p = $obj->checkArgument("p", $_GET, "2");
$nc = $obj->checkArgument("nc", $_GET, "0");
$num = $obj->checkArgument("num", $_GET, 0);
$limit = $obj->checkArgument("limit", $_GET, 20);
$instance = $obj->checkArgument("instance", $_GET, $obj->defaultPoller);
$hostgroups = $obj->checkArgument("hostgroups", $_GET, $obj->defaultHostgroups);
$hSearch = $obj->checkArgument("host_search", $_GET, "");
$sgSearch = $obj->checkArgument("sg_search", $_GET, "");
$sort_type = $obj->checkArgument("sort_type", $_GET, "host_name");
$order = $obj->checkArgument("order", $_GET, "ASC");
$dateFormat = $obj->checkArgument("date_time_format_status", $_GET, "Y/m/d H:i:s");
$queryValues = array();
$o = filter_input(INPUT_GET, 'o', FILTER_SANITIZE_STRING, array('options' => array('default' => 'h')));
$p = filter_input(INPUT_GET, 'p', FILTER_VALIDATE_INT, array('options' => array('default' => 2)));
$num = filter_input(INPUT_GET, 'num', FILTER_VALIDATE_INT, array('options' => array('default' => 0)));
$limit = filter_input(INPUT_GET, 'limit', FILTER_VALIDATE_INT, array('options' => array('default' => 20)));
//if instance value is not set, displaying all active pollers linked resources
$instance = filter_var($obj->defaultPoller ?? -1, FILTER_VALIDATE_INT);
$hSearch = filter_input(INPUT_GET, 'host_search', FILTER_SANITIZE_STRING, array('options' => array('default' => '')));
$sgSearch = filter_input(INPUT_GET, 'sg_search', FILTER_SANITIZE_STRING, array('options' => array('default' => '')));
$sort_type = filter_input(
INPUT_GET,
'sort_type',
FILTER_SANITIZE_STRING,
array('options' => array('default' => 'host_name'))
);
$order = filter_input(
INPUT_GET,
'order',
FILTER_VALIDATE_REGEXP,
array('options' => array('default' => 'ASC', 'regexp' => '/^(ASC|DESC)$/'))
);

//saving bound values
$queryValues = [];
$queryValues2 = [];

// Backup poller selection
$obj->setInstanceHistory($instance);
Expand All @@ -97,16 +105,16 @@
}

// this query allows to manage pagination
$query = "SELECT SQL_CALC_FOUND_ROWS DISTINCT sg.servicegroup_id, h.host_id "
. "FROM servicegroups sg, services_servicegroups sgm, hosts h, services s ";
$query = "SELECT SQL_CALC_FOUND_ROWS DISTINCT sg.servicegroup_id, h.host_id
FROM servicegroups sg, services_servicegroups sgm, hosts h, services s ";

if (!$obj->is_admin) {
$query .= ", centreon_acl ";
}

$query .= "WHERE sgm.servicegroup_id = sg.servicegroup_id "
. "AND sgm.host_id = h.host_id "
. "AND sgm.service_id = s.service_id ";
$query .= "WHERE sgm.servicegroup_id = sg.servicegroup_id
AND sgm.host_id = h.host_id
AND sgm.service_id = s.service_id ";

// filter elements with acl (host, service, servicegroup)
if (!$obj->is_admin) {
Expand All @@ -119,18 +127,20 @@

// Servicegroup search
if ($sgSearch != "") {
$query .= "AND sg.name = :sgSearch ";
$queryValues[':sgSearch'] = [
PDO::PARAM_STR => $sgSearch
$query .= " AND sg.name = :sgSearch ";
$queryValues['sgSearch'] = [
\PDO::PARAM_STR => $sgSearch
];
}

// Host search
$h_search = '';
if ($hSearch != "") {
$h_search .= "AND h.name like :hSearch ";
$queryValues[':hSearch'] = [
PDO::PARAM_STR => "%" . $hSearch . "%"
$h_search .= " AND h.name LIKE :hSearch ";
// as this partial request is used in two queries, we need to bound it two times using two arrays
// to avoid incoherent number of bound variables in the second query
$queryValues['hSearch'] = $queryValues2['hSearch'] = [
\PDO::PARAM_STR => "%" . $hSearch . "%"
];
}
$query .= $h_search;
Expand All @@ -141,26 +151,25 @@
// Poller search
if ($instance != -1) {
$query .= " AND h.instance_id = :instance ";
$queryValues[':instance'] = [
PDO::PARAM_INT => $instance
$queryValues['instance'] = [
\PDO::PARAM_INT => $instance
];
}
$query .= "ORDER BY sg.name " . $order
. " LIMIT :numLimit, :limit";
$queryValues[':numLimit'] = [
PDO::PARAM_INT => (int) ($num * $limit)
$query .= " ORDER BY sg.name " . $order . " LIMIT :numLimit, :limit";
$queryValues['numLimit'] = [
\PDO::PARAM_INT => (int)($num * $limit)
];
$queryValues[':limit'] = [
PDO::PARAM_INT => (int) $limit
$queryValues['limit'] = [
\PDO::PARAM_INT => (int)$limit
];

$DBRESULT = $obj->DBC->prepare($query);
$dbResult = $obj->DBC->prepare($query);
foreach ($queryValues as $bindId => $bindData) {
foreach ($bindData as $bindType => $bindValue) {
$DBRESULT->bindValue($bindId, $bindValue, $bindType);
$dbResult->bindValue($bindId, $bindValue, $bindType);
}
}
$DBRESULT->execute();
$dbResult->execute();
$numRows = $obj->DBC->query("SELECT FOUND_ROWS()")->fetchColumn();

// Create XML Flow
Expand All @@ -183,7 +192,7 @@
if ($numRows > 0) {
$sg_search .= "AND (";
$servicegroups = array();
while ($row = $DBRESULT->fetch()) {
while ($row = $dbResult->fetch()) {
$servicesgroups[$row['servicegroup_id']][] = $row['host_id'];
}
$servicegroupsSql1 = array();
Expand All @@ -192,27 +201,33 @@
foreach ($value as $hostId) {
$hostsSql[] = $hostId;
}
$servicegroupsSql1[] = "(sg.servicegroup_id = " . $key . " AND h.host_id IN (" .
implode(',', $hostsSql) . ")) ";
$servicegroupsSql1[] = "(sg.servicegroup_id = " . $key .
" AND h.host_id IN (" . implode(',', $hostsSql) . ")) ";
}
$sg_search .= implode(" OR ", $servicegroupsSql1);
$sg_search .= ") ";
if ($sgSearch != "") {
$sg_search .= "AND sg.name = '" . $sgSearch . "' ";
$sg_search .= "AND sg.name = :sgSearch";
$queryValues2['sgSearch'] = [
\PDO::PARAM_STR => $sgSearch
];
}

$query2 = "SELECT SQL_CALC_FOUND_ROWS DISTINCT sg.name AS sg_name, sg.name as alias, h.name as host_name, "
. "h.state as host_state, h.icon_image, h.host_id, s.state, s.description, s.service_id, "
. "(case s.state when 0 then 3 when 2 then 0 when 3 then 2 else s.state END) as tri "
. "FROM servicegroups sg, services_servicegroups sgm, services s, hosts h ";
$query2 = "SELECT SQL_CALC_FOUND_ROWS DISTINCT sg.name AS sg_name,
sg.name AS alias,
h.name AS host_name,
h.state as host_state,
h.icon_image, h.host_id, s.state, s.description, s.service_id,
(CASE s.state WHEN 0 THEN 3 WHEN 2 THEN 0 WHEN 3 THEN 2 ELSE s.state END) AS tri
FROM servicegroups sg, services_servicegroups sgm, services s, hosts h ";

if (!$obj->is_admin) {
$query2 .= ", centreon_acl ";
}

$query2 .= "WHERE sgm.servicegroup_id = sg.servicegroup_id "
. "AND sgm.host_id = h.host_id "
. "AND sgm.service_id = s.service_id ";
$query2 .= "WHERE sgm.servicegroup_id = sg.servicegroup_id
AND sgm.host_id = h.host_id
AND sgm.service_id = s.service_id ";

// filter elements with acl (host, service, servicegroup)
if (!$obj->is_admin) {
Expand All @@ -224,15 +239,21 @@
}
$query2 .= $sg_search . $h_search . $s_search . " ORDER BY sg_name, tri ASC";

$DBRESULT = $obj->DBC->query($query2);
$dbResult = $obj->DBC->prepare($query2);
foreach ($queryValues2 as $bindId => $bindData) {
foreach ($bindData as $bindType => $bindValue) {
$dbResult->bindValue($bindId, $bindValue, $bindType);
}
}
$dbResult->execute();

$ct = 0;
$sg = "";
$h = "";
$flag = 0;
$count = 0;

while ($tab = $DBRESULT->fetch()) {
while ($tab = $dbResult->fetch()) {
if (!isset($aTab[$tab["sg_name"]])) {
$aTab[$tab["sg_name"]] = array(
'sgn' => CentreonUtils::escapeSecure($tab["sg_name"]),
Expand All @@ -250,21 +271,19 @@
}
$aTab[$tab["sg_name"]]['host'][$tab["host_name"]] = array(
'h' => $tab["host_name"],
'hs' => $tab["host_state"],
'hs' => _($obj->statusHost[$tab["host_state"]]),
'hn' => CentreonUtils::escapeSecure($tab["host_name"]),
'hico' => $icone,
'hnl' => CentreonUtils::escapeSecure(urlencode($tab["host_name"])),
'hid' => $tab["host_id"],
"hcount" => $count,
"hs" => _($obj->statusHost[$tab["host_state"]]),
"hc" => $obj->colorHost[$tab["host_state"]],
'service' => array()
);
}

if (!isset($aTab[$tab["sg_name"]]['host'][$tab["host_name"]]['service'][$tab['description']])) {
$aTab[$tab["sg_name"]]['host'][$tab["host_name"]]['service'][$tab['description']] = array(

"sn" => CentreonUtils::escapeSecure($tab['description']),
"snl" => CentreonUtils::escapeSecure(urlencode($tab['description'])),
"sc" => $obj->colorService[$tab['state']],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@
array('options' => array('default' => 'ASC', 'regexp' => '/^(ASC|DESC)$/'))
);

//saving bound values
$queryValues = [];
$queryValues2 = [];

/*
* Backup poller selection
*/
Expand Down Expand Up @@ -121,13 +125,21 @@

// Servicegroup search
if ($sgSearch != "") {
$query .= "AND sg.name = '" . $sgSearch . "' ";
$query .= "AND sg.name = :sgSearch ";
$queryValues['sgSearch'] = [
\PDO::PARAM_STR => $sgSearch
];
}

// Host search
$h_search = '';
if ($hSearch != "") {
$h_search .= "AND h.name like '%" . $hSearch . "%' ";
$h_search .= " AND h.name LIKE :hSearch ";
// as this partial request is used in two queries, we need to bound it two times using two arrays
// to avoid incoherent number of bound variables in the second query
$queryValues['hSearch'] = $queryValues2['hSearch'] = [
\PDO::PARAM_STR => "%" . $hSearch . "%"
];
}
$query .= $h_search;

Expand All @@ -136,13 +148,27 @@

// Poller search
if ($instance != -1) {
$query .= " AND h.instance_id = " . $instance . " ";
$query .= " AND h.instance_id = :instance ";
$queryValues['instance'] = [
\PDO::PARAM_INT => $instance
];
}

$query .= "ORDER BY sg.name " . $order . " LIMIT " . ($num * $limit) . ", " . $limit;

$DBRESULT = $obj->DBC->query($query);
$query .= "ORDER BY sg.name " . $order . " LIMIT :numLimit, :limit";
$queryValues['numLimit'] = [
\PDO::PARAM_INT => (int)($num * $limit)
];
$queryValues['limit'] = [
\PDO::PARAM_INT => (int)$limit
];

$dbResult = $obj->DBC->prepare($query);
foreach ($queryValues as $bindId => $bindData) {
foreach ($bindData as $bindType => $bindValue) {
$dbResult->bindValue($bindId, $bindValue, $bindType);
}
}
$dbResult->execute();
$numRows = $obj->DBC->query("SELECT FOUND_ROWS()")->fetchColumn();

/**
Expand Down Expand Up @@ -170,7 +196,7 @@
if ($numRows > 0) {
$sg_search .= "AND (";
$servicegroups = array();
while ($row = $DBRESULT->fetchRow()) {
while ($row = $dbResult->fetch()) {
$servicesgroups[$row['servicegroup_id']][] = $row['host_id'];
}
$servicegroupsSql1 = array();
Expand All @@ -185,7 +211,10 @@
$sg_search .= implode(" OR ", $servicegroupsSql1);
$sg_search .= ") ";
if ($sgSearch != "") {
$sg_search .= "AND sg.name = '" . $sgSearch . "' ";
$sg_search .= "AND sg.name = :sgSearch";
$queryValues2['sgSearch'] = [
\PDO::PARAM_STR => $sgSearch
];
}

$query2 = "SELECT SQL_CALC_FOUND_ROWS count(s.state) as count_state,
Expand All @@ -204,7 +233,13 @@
. $obj->access->queryBuilder("AND", "s.service_id", $obj->access->getServicesString("ID", $obj->DBC))
. " GROUP BY sg_name,host_name,host_state,icon_image,host_id, s.state ORDER BY tri ASC ";

$DBRESULT = $obj->DBC->query($query2);
$dbResult = $obj->DBC->prepare($query2);
foreach ($queryValues2 as $bindId => $bindData) {
foreach ($bindData as $bindType => $bindValue) {
$dbResult->bindValue($bindId, $bindValue, $bindType);
}
}
$dbResult->execute();

$states = array(
0 => 'sk',
Expand All @@ -215,7 +250,7 @@
);

$sg_list = array();
while ($tab = $DBRESULT->fetchRow()) {
while ($tab = $dbResult->fetch()) {
$sg_list[$tab["sg_name"]][$tab["host_name"]]['host_id'] = $tab['host_id'];
$sg_list[$tab["sg_name"]][$tab["host_name"]]['icon_image'] = $tab['icon_image'];
$sg_list[$tab["sg_name"]][$tab["host_name"]]['host_state'] = $tab['host_state'];
Expand Down

0 comments on commit 0ee8451

Please sign in to comment.