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

fix(secu): Avoid SQL injections in service by servicegroup pages #8065

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,27 @@
$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')));
$o = filter_input(INPUT_GET, 'o', 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)));
$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)$/'))
);
$queryValues = [];
$queryValues2 = [];

// Backup poller selection
$obj->setInstanceHistory($instance);
Expand All @@ -97,16 +102,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 +124,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 +148,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 +189,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 +198,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 +236,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 +268,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 @@ -121,13 +121,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 +144,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 +192,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 +207,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 +229,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 +246,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