From 54e4d0910addf88b79c1778e5c6957f5b7d6c665 Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Wed, 29 May 2019 09:39:17 -0500 Subject: [PATCH] Sanitize report name in pdf.php (#10270) Authentication users could include arbitrary file. --- LibreNMS/Util/Clean.php | 78 +++++++++++++++++++ LibreNMS/Util/Html.php | 32 -------- .../Controllers/Widgets/NotesController.php | 2 +- html/pdf.php | 27 ++++--- includes/common.php | 2 +- 5 files changed, 95 insertions(+), 46 deletions(-) create mode 100644 LibreNMS/Util/Clean.php diff --git a/LibreNMS/Util/Clean.php b/LibreNMS/Util/Clean.php new file mode 100644 index 0000000000..f82bb4481d --- /dev/null +++ b/LibreNMS/Util/Clean.php @@ -0,0 +1,78 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2019 Tony Murray + * @author Tony Murray + */ + +namespace LibreNMS\Util; + +use HTMLPurifier; +use HTMLPurifier_Config; +use LibreNMS\Config; + +class Clean +{ + /** + * Sanitize file name by removing all invalid characters. + * Does not make the string safe for javascript or sql! + * + * @param string $file + * @return string|string[]|null + */ + public static function fileName($file) + { + return preg_replace('/[^a-zA-Z0-9\-._]/', '', $file); + } + + /** + * Clean a string for display in an html page. + * For use in non-blade pages + * + * @param $value + * @param array $purifier_config (key, value pair) + * @return string + */ + public static function html($value, $purifier_config = []) + { + /** @var HTMLPurifier $purifier */ + static $purifier; + + // If $purifier_config is non-empty then we don't want + // to convert html tags and allow these to be controlled + // by purifier instead. + if (empty($purifier_config)) { + $value = htmlentities($value); + } + + if (!isset($purifier)) { + // initialize HTML Purifier here since this is the only user + $p_config = HTMLPurifier_Config::createDefault(); + $p_config->set('Cache.SerializerPath', Config::get('temp_dir', '/tmp')); + foreach ($purifier_config as $k => $v) { + $p_config->set($k, $v); + } + $purifier = new HTMLPurifier($p_config); + } + + return $purifier->purify(stripslashes($value)); + } +} diff --git a/LibreNMS/Util/Html.php b/LibreNMS/Util/Html.php index ab6bce8c1d..893c489eee 100644 --- a/LibreNMS/Util/Html.php +++ b/LibreNMS/Util/Html.php @@ -119,36 +119,4 @@ class Html return $output; } - - /** - * Clean a string for display in an html page. - * - * @param $value - * @param array $purifier_config (key, value pair) - * @return string - */ - public static function display($value, $purifier_config = []) - { - /** @var HTMLPurifier $purifier */ - static $purifier; - - // If $purifier_config is non-empty then we don't want - // to convert html tags and allow these to be controlled - // by purifier instead. - if (empty($purifier_config)) { - $value = htmlentities($value); - } - - if (!isset($purifier)) { - // initialize HTML Purifier here since this is the only user - $p_config = HTMLPurifier_Config::createDefault(); - $p_config->set('Cache.SerializerPath', Config::get('temp_dir', '/tmp')); - foreach ($purifier_config as $k => $v) { - $p_config->set($k, $v); - } - $purifier = new HTMLPurifier($p_config); - } - - return $purifier->purify(stripslashes($value)); - } } diff --git a/app/Http/Controllers/Widgets/NotesController.php b/app/Http/Controllers/Widgets/NotesController.php index c2b11b3b45..688f22a25e 100644 --- a/app/Http/Controllers/Widgets/NotesController.php +++ b/app/Http/Controllers/Widgets/NotesController.php @@ -51,7 +51,7 @@ class NotesController extends WidgetController 'HTML.SafeIframe' => true, 'URI.SafeIframeRegexp' => '%^(https?:)?//%', ]; - $output = Html::display(nl2br($settings['notes']), $purifier_config); + $output = \LibreNMS\Util\Clean::html(nl2br($settings['notes']), $purifier_config); return $output; } diff --git a/html/pdf.php b/html/pdf.php index d0c2f4d136..aed0dbf6d1 100644 --- a/html/pdf.php +++ b/html/pdf.php @@ -12,12 +12,12 @@ * the source code distribution for details. */ -use LibreNMS\Authentication\LegacyAuth; +use LibreNMS\Config; -$init_modules = array('web', 'auth'); +$init_modules = ['web', 'auth']; require realpath(__DIR__ . '/..') . '/includes/init.php'; -if (!LegacyAuth::check()) { +if (!Auth::check()) { die('Unauthorized'); } @@ -25,11 +25,13 @@ set_debug(strpos($_SERVER['PATH_INFO'], 'debug')); $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); -$pdf->SetCreator($config['project_name']); -$pdf->SetAuthor($config['project_name']); -$pdf->setFooterData(array(0, 64, 0), array(0, 64, 128)); -$pdf->setHeaderFont(array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN)); -$pdf->setFooterFont(array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA)); +$project_name = Config::get('project_name'); + +$pdf->SetCreator($project_name); +$pdf->SetAuthor($project_name); +$pdf->setFooterData([0, 64, 0], [0, 64, 128]); +$pdf->setHeaderFont([PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN]); +$pdf->setFooterFont([PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA]); $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); $pdf->SetHeaderMargin(PDF_MARGIN_HEADER); @@ -38,11 +40,12 @@ $pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM); $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); $pdf->setFontSubsetting(true); $pdf->SetFont('helvetica', '', 14, '', true); -$pdf->setTextShadow(array('enabled' => false, 'depth_w' => 0.2, 'depth_h' => 0.2, 'color' => array(196, 196, 196), 'opacity' => 1, 'blend_mode' => 'Normal')); +$pdf->setTextShadow(['enabled' => false, 'depth_w' => 0.2, 'depth_h' => 0.2, 'color' => [196, 196, 196], 'opacity' => 1, 'blend_mode' => 'Normal']); -if (isset($_GET['report']) && !empty($_GET['report'])) { - $report = mres($_GET['report']); - $pdf->SetHeaderData('../../../../../html/'.$config['title_image'], 40, ucfirst($report), $config['project_name'], array(0, 0, 0), array(0, 64, 128)); +if (!empty($_GET['report'])) { + $report = \LibreNMS\Util\Clean::fileName($_GET['report']); + $image = base_path('html/' . Config::get('title_image')); + $pdf->SetHeaderData($image, 40, ucfirst($report), $project_name, [0, 0, 0], [0, 64, 128]); include_once "includes/html/reports/$report.pdf.inc.php"; } else { $report = 'report'; diff --git a/includes/common.php b/includes/common.php index 842e4341c6..60995a183b 100644 --- a/includes/common.php +++ b/includes/common.php @@ -1523,7 +1523,7 @@ function clean($value, $strip_tags = true) */ function display($value, $purifier_config = []) { - return Html::display($value, $purifier_config); + return \LibreNMS\Util\Clean::html($value, $purifier_config); } /**