Skip to content
Draft
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
2 changes: 1 addition & 1 deletion .github/workflows/plugin-ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ jobs:
run: sudo apt-get update

- name: Install System Dependencies
run: sudo apt-get install -y apache2 snmp snmpd rrdtool fping libapache2-mod-php${{ matrix.php }}
run: sudo apt-get install -y apache2 snmp snmpd rrdtool fping

- name: Start SNMPD Agent and Test
run: |
Expand Down
26 changes: 23 additions & 3 deletions functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ function syslog_sendemail($to, $from, $subject, $message, $smsmessage = '') {
}
}

define('SYSLOG_IMPORT_MAX_BYTES', 5242880);

function syslog_get_import_xml_payload($redirect_url) {
if (trim(get_nfilter_request_var('import_text')) != '') {
// textbox input
Expand All @@ -166,6 +168,13 @@ function syslog_get_import_xml_payload($redirect_url) {
exit;
}

$size = isset($_FILES['import_file']['size']) ? (int) $_FILES['import_file']['size'] : filesize($tmp_name);
if ($size <= 0 || $size > SYSLOG_IMPORT_MAX_BYTES) {
cacti_log('SYSLOG ERROR: Uploaded import file has an invalid size', false, 'SYSTEM');
header('Location: ' . $redirect_url);
exit;
}

$fp = fopen($tmp_name, 'rb');

if ($fp === false) {
Expand All @@ -174,7 +183,7 @@ function syslog_get_import_xml_payload($redirect_url) {
exit;
}

$xml_data = fread($fp, filesize($tmp_name));
$xml_data = fread($fp, $size);
fclose($fp);

if ($xml_data === false) {
Expand All @@ -190,6 +199,17 @@ function syslog_get_import_xml_payload($redirect_url) {
exit;
}

function syslog_csv_cell($value) {
$value = (string) $value;
$trimmed = ltrim($value, " \t\r\n");

if ($trimmed !== '' && in_array($trimmed[0], ['=', '+', '-', '@'], true)) {
return "'" . $value;
}

return $value;
}

function syslog_is_partitioned() {
global $syslogdb_default;

Expand Down Expand Up @@ -897,7 +917,7 @@ function syslog_export($tab) {
$host = trim($message['host'], ' =+-@');
$logmsg = trim($message['logmsg'], ' =+-@');

$line = [
$line = array_map('syslog_csv_cell', [
$message['name'],
$severity,
$message['logtime'],
Expand All @@ -906,7 +926,7 @@ function syslog_export($tab) {
ucfirst($message['facility']),
ucfirst($message['priority']),
$message['count']
];
]);

fputcsv($fp, $line);
}
Expand Down
2 changes: 1 addition & 1 deletion syslog.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ function syslog_view_alarm() {
WHERE seq = ?",
[get_request_var('id')]);

print trim($html, "' ");
print nl2br(html_escape(trim($html, "' ")));

print '</td></tr></table>';

Expand Down
28 changes: 28 additions & 0 deletions tests/regression/issue318_output_import_hardening_test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

$functions = file_get_contents(__DIR__ . '/../../functions.php');
$syslog = file_get_contents(__DIR__ . '/../../syslog.php');

if ($functions === false || $syslog === false) {
fwrite(STDERR, "Unable to read Syslog sources\n");
exit(1);
}

foreach ([
'SYSLOG_IMPORT_MAX_BYTES',
'$size <= 0 || $size > SYSLOG_IMPORT_MAX_BYTES',
'function syslog_csv_cell($value)',
"array_map('syslog_csv_cell'",
] as $needle) {
if (strpos($functions, $needle) === false) {
fwrite(STDERR, "Missing import/export hardening: $needle\n");
exit(1);
}
}

if (strpos($syslog, 'nl2br(html_escape(trim($html, "\' ")))') === false) {
fwrite(STDERR, "Alert viewer must escape stored HTML\n");
exit(1);
}

echo "issue318_output_import_hardening_test passed\n";
Loading