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

Commit

Permalink
fix(secu): prevent from sql injections in services pages (#8082)
Browse files Browse the repository at this point in the history
* prevent sql injection in makeXMLForOneHostXML.php

* prevent sql injection in makeXMLForOneServiceXML.php

* prevent sql injection in serviceXML.php

* prevent sql injection in serviceGridXML.php

* prevent sql injection in serviceXML.php

* prevent sql injection in serviceSummaryXML.php

* remove debug and prepare second query

* style
  • Loading branch information
sc979 committed Nov 12, 2019
1 parent 8c20669 commit ff6d949
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 244 deletions.
77 changes: 38 additions & 39 deletions www/include/monitoring/status/Services/xml/makeXMLForOneHost.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
/*
* Check Arguments From GET tab
*/
$host_id = filter_input(INPUT_GET, 'host_id', FILTER_VALIDATE_INT, array('options' => array('default' => false)));
$hostId = filter_input(INPUT_GET, 'host_id', FILTER_VALIDATE_INT, ['options' => ['default' => false]]);

if ($host_id === false) {
if ($hostId === false) {
print _("Bad host ID");
exit();
}
Expand All @@ -74,7 +74,7 @@
if (!$isAdmin) {
$userId = $centreon->user->user_id;
$acl = new CentreonACL($userId, $isAdmin);
if (!$acl->checkHost($host_id)) {
if (!$acl->checkHost($hostId)) {
print _("You don't have access to this resource");
exit();
}
Expand All @@ -83,46 +83,45 @@
/**
* Get Host status
*/
$rq1 = " SELECT h.state," .
" h.address," .
" h.name," .
" h.alias," .
" i.name AS poller, " .
" h.perfdata," .
" h.check_attempt," .
" h.state_type," .
" h.last_check, " .
" h.next_check, " .
" h.latency," .
" h.execution_time," .
" h.last_state_change," .
" h.last_notification," .
" h.next_host_notification," .
" h.last_hard_state_change," .
" h.last_hard_state," .
" h.last_time_up," .
" h.last_time_down," .
" h.last_time_unreachable," .
" h.notification_number," .
" h.scheduled_downtime_depth," .
" h.output," .
" h.notes," .
" h.notify," .
" h.event_handler_enabled," .
" h.icon_image, " .
" h.timezone" .
" FROM hosts h, instances i " .
" WHERE h.host_id = " . $host_id .
" AND h.instance_id = i.instance_id " .
" LIMIT 1";

$DBRESULT = $obj->DBC->query($rq1);
$rq1 = "SELECT h.state,
h.address,
h.name,
h.alias,
i.name AS poller,
h.perfdata,
h.check_attempt,
h.state_type,
h.last_check,
h.next_check,
h.latency,
h.execution_time,
h.last_state_change,
h.last_notification,
h.next_host_notification,
h.last_hard_state_change,
h.last_hard_state,
h.last_time_up,
h.last_time_down,
h.last_time_unreachable,
h.notification_number,
h.scheduled_downtime_depth,
h.output,
h.notes,
h.notify,
h.event_handler_enabled,
h.icon_image,
h.timezone
FROM hosts h, instances i
WHERE h.host_id = :hostId AND h.instance_id = i.instance_id LIMIT 1";
$dbResult = $obj->DBC->prepare($rq1);
$dbResult->bindValue(':hostId', $hostId, \PDO::PARAM_INT);
$dbResult->execute();

/*
* Start Buffer
*/
$obj->XML->startElement("reponse");
if ($data = $DBRESULT->fetch()) {
if ($data = $dbResult->fetch()) {
// Split the plugin_output
$outputLines = explode("\n", $data['output']);
$pluginShortOuput = $outputLines[0];
Expand Down Expand Up @@ -220,7 +219,7 @@
} else {
$obj->XML->writeElement("infos", "none");
}
$DBRESULT->closeCursor();
$dbResult->closeCursor();

// Translations
$obj->XML->writeElement("tr1", _("Check information"), 0);
Expand Down
79 changes: 40 additions & 39 deletions www/include/monitoring/status/Services/xml/makeXMLForOneService.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,18 @@
/*
* Check Arguments From GET tab
*/
$svc_id = filter_input(INPUT_GET, 'svc_id', FILTER_SANITIZE_STRING, array('options' => array('default' => 0)));
$svcId = filter_input(INPUT_GET, 'svc_id', FILTER_SANITIZE_STRING, array('options' => array('default' => 0)));

// splitting the host/service combination
if (!empty($svc_id)) {
$tab = preg_split('/\_/', $svc_id);
if (!empty($svcId)) {
$tab = preg_split('/\_/', $svcId);
}

// checking splitted values consistency
$host_id = filter_var($tab[0] ?? null, FILTER_VALIDATE_INT);
$service_id = filter_var($tab[1] ?? null, FILTER_VALIDATE_INT);
$hostId = filter_var($tab[0] ?? null, FILTER_VALIDATE_INT);
$serviceId = filter_var($tab[1] ?? null, FILTER_VALIDATE_INT);

if ($host_id === false || $service_id === false) {
if ($hostId === false || $serviceId === false) {
print _("Bad service ID");
exit();
}
Expand All @@ -83,7 +83,7 @@
if (!$isAdmin) {
$userId = $centreon->user->user_id;
$acl = new CentreonACL($userId, $isAdmin);
if (!$acl->checkService($service_id)) {
if (!$acl->checkService($serviceId)) {
print _("You don't have access to this resource");
exit();
}
Expand All @@ -92,42 +92,43 @@
/*
* Get Service status
*/
$rq1 = "SELECT s.state," .
" h.name, " .
" s.description," .
" s.last_check," .
" s.next_check," .
" s.last_state_change," .
" s.last_notification," .
" s.last_hard_state_change," .
" s.last_hard_state," .
" s.latency," .
" s.last_time_ok," .
" s.last_time_critical," .
" s.last_time_unknown," .
" s.last_time_warning," .
" s.notification_number," .
" s.scheduled_downtime_depth," .
" s.output," .
" s.notes," .
" ROUND(s.percent_state_change) as percent_state_change," .
" s.notify," .
" s.perfdata," .
" s.state_type," .
" s.execution_time," .
" s.event_handler_enabled, " .
" s.icon_image, " .
" s.display_name " .
" FROM hosts h, services s " .
" WHERE s.host_id = h.host_id " .
" AND s.host_id = $host_id AND service_id = $service_id LIMIT 1";
$rq1 = "SELECT s.state,
h.name,
s.description,
s.last_check,
s.next_check,
s.last_state_change,
s.last_notification,
s.last_hard_state_change,
s.last_hard_state,
s.latency,
s.last_time_ok,
s.last_time_critical,
s.last_time_unknown,
s.last_time_warning,
s.notification_number,
s.scheduled_downtime_depth,
s.output,
s.notes,
ROUND(s.percent_state_change) as percent_state_change,
s.notify,
s.perfdata,
s.state_type,
s.execution_time,
s.event_handler_enabled,
s.icon_image,
s.display_name
FROM hosts h, services s WHERE s.host_id = h.host_id
AND s.host_id = :hostId AND service_id = :serviceId LIMIT 1";
$dbResult = $obj->DBC->prepare($rq1);
$dbResult->bindValue(':hostId', $hostId, \PDO::PARAM_INT);
$dbResult->bindValue(':serviceId', $serviceId, \PDO::PARAM_INT);
$dbResult->execute();

// Init Buffer
$obj->XML->startElement("reponse");

// Request
$DBRESULT = $obj->DBC->query($rq1);
if ($data = $DBRESULT->fetch()) {
if ($data = $dbResult->fetch()) {
/* Split the plugin_output */
$outputLines = preg_split('/<br \/>|<br>|\\\n|\x0A|\x0D\x0A|\n/', $data['output']);
if (strlen($outputLines[0]) > 100) {
Expand Down
64 changes: 37 additions & 27 deletions www/include/monitoring/status/Services/xml/serviceGridXML.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,35 +56,32 @@
$obj->getDefaultFilters();

// Check Arguments From GET tab
$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)));
$o = filter_input(INPUT_GET, 'o', FILTER_SANITIZE_STRING, ['options' => ['default' => 'h']]);
$p = filter_input(INPUT_GET, 'p', FILTER_VALIDATE_INT, ['options' => ['default' => 2]]);
$num = filter_input(INPUT_GET, 'num', FILTER_VALIDATE_INT, ['options' => ['default' => 0]]);
$limit = filter_input(INPUT_GET, 'limit', FILTER_VALIDATE_INT, ['options' => ['default' => 20]]);
//if instance value is not set, displaying all active pollers linked resources
$instance = filter_var($obj->defaultPoller ?? -1, FILTER_VALIDATE_INT);
$hostgroups = filter_var($obj->defaultHostgroups ?? 0, FILTER_VALIDATE_INT);
$search = filter_input(INPUT_GET, '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'))
);
$search = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_STRING, ['options' => ['default' => '']]);
$sortType = filter_input(INPUT_GET, 'sort_type', FILTER_SANITIZE_STRING, ['options' => ['default' => 'host_name']]);
$order = filter_input(
INPUT_GET,
'order',
FILTER_VALIDATE_REGEXP,
array('options' => array('default' => 'ASC', 'regexp' => '/^(ASC|DESC)$/'))
['options' => ['default' => 'ASC', 'regexp' => '/^(ASC|DESC)$/']]
);

// Backup poller selection
$obj->setInstanceHistory($instance);

//saving bound values
$queryValues = [];

/**
* Get Host status
*/
$rq1 = " SELECT SQL_CALC_FOUND_ROWS DISTINCT hosts.name, hosts.state, hosts.icon_image, hosts.host_id " .
" FROM hosts ";
$rq1 = " SELECT SQL_CALC_FOUND_ROWS DISTINCT hosts.name, hosts.state, hosts.icon_image, hosts.host_id FROM hosts ";
if ($hostgroups) {
$rq1 .= ", hosts_hostgroups hg, hostgroups hg2 ";
}
Expand All @@ -93,8 +90,8 @@
}
$rq1 .= " WHERE hosts.name NOT LIKE '_Module_%' ";
if (!$obj->is_admin) {
$rq1 .= " AND hosts.host_id = centreon_acl.host_id ";
$rq1 .= $obj->access->queryBuilder("AND", "group_id", $obj->grouplistStr);
$rq1 .= " AND hosts.host_id = centreon_acl.host_id " .
$obj->access->queryBuilder("AND", "group_id", $obj->grouplistStr);
}
if ($o == "svcgrid_pb" || $o == "svcOV_pb" || $o == "svcgrid_ack_0" || $o == "svcOV_ack_0") {
$rq1 .= " AND hosts.host_id IN (" .
Expand All @@ -107,30 +104,43 @@
" WHERE s.acknowledged = '1' AND s.enabled = 1)";
}
if ($search != "") {
$rq1 .= " AND hosts.name like '%" . $search . "%' ";
$rq1 .= " AND hosts.name like :search ";
$queryValues['search'] = [\PDO::PARAM_STR => '%' . $search . '%'];
}
if ($instance != -1) {
$rq1 .= " AND hosts.instance_id = " . $instance . "";
$rq1 .= " AND hosts.instance_id = :instance ";
$queryValues['instance'] = [\PDO::PARAM_INT => $instance];
}
if ($hostgroups) {
$rq1 .= " AND hosts.host_id = hg.host_id ";
$rq1 .= " AND hg.hostgroup_id IN (" . $hostgroups . ") ";
$rq1 .= " AND hg.hostgroup_id = hg2.hostgroup_id ";
$rq1 .= " AND hosts.host_id = hg.host_id
AND hg.hostgroup_id IN (:hostgroup)
AND hg.hostgroup_id = hg2.hostgroup_id ";
// only one value is returned from the current "select" filter
$queryValues['hostgroup'] = [\PDO::PARAM_INT => $hostgroups];
}
$rq1 .= " AND hosts.enabled = 1 ";

switch ($sort_type) {
switch ($sortType) {
case 'current_state':
$rq1 .= " ORDER BY hosts.state " . $order . ",hosts.name ";
break;
default:
$rq1 .= " ORDER BY hosts.name " . $order;
break;
}
$rq1 .= " LIMIT " . ($num * $limit) . "," . $limit;
$rq1 .= " LIMIT :numLimit, :limit";
$queryValues['numLimit'] = [\PDO::PARAM_INT => ($num * $limit)];
$queryValues['limit'] = [\PDO::PARAM_INT => $limit];

// Execute request
$DBRESULT = $obj->DBC->query($rq1);
$dbResult = $obj->DBC->prepare($rq1);
foreach ($queryValues as $bindId => $bindData) {
foreach ($bindData as $bindType => $bindValue) {
$dbResult->bindValue($bindId, $bindValue, $bindType);
}
}
$dbResult->execute();

$numRows = $obj->DBC->numberRows();

$obj->XML->startElement("reponse");
Expand All @@ -143,9 +153,9 @@
preg_match("/svcOV/", $_GET["o"], $matches) ? $obj->XML->writeElement("s", "1") : $obj->XML->writeElement("s", "0");
$obj->XML->endElement();

$tab_final = array();
$tab_final = [];
$str = "";
while ($ndo = $DBRESULT->fetch()) {
while ($ndo = $dbResult->fetch()) {
if ($str != "") {
$str .= ",";
}
Expand All @@ -157,7 +167,7 @@
$tabIcone[$ndo["name"]] = "none";
}
}
$DBRESULT->closeCursor();
$dbResult->closeCursor();

// Get Service status
$tab_svc = $obj->monObj->getServiceStatus($str, $obj, $o, $instance, $hostgroups);
Expand Down
Loading

0 comments on commit ff6d949

Please sign in to comment.