From 4a737bc1abdbef7e0698b006704a26583a4c61df Mon Sep 17 00:00:00 2001
From: Peter Wu
Date: Sun, 20 Jul 2014 23:30:49 +0200
Subject: Use a more secure command line building method
Previously, a command is built by string concatenation. Here, the
distinction between a value and multiple params got lost. Solve this
by using an array for shell arguments. As the escaping is now removed
from the `rrd_gen_graph` function, the canvas style needs to manually
add those quotes to make the JS code still work. That only supports
double-quotes, so hopefully nobody creates a name with a double quote
as that would break the fragile JS command line parser.
Separate the rrdtool options from the rrdtool graph command to make the
`$graph_type == 'canvas'` option work (it would otherwise not understand
the `rrdtool graph - -a PNG` option).
Merge the SVG and PNG cases as they are the same except for the
Content-Type header.
Fix a missing html escape in a debug style.
---
type/Base.class.php | 104 ++++++++++++++++++++++++++++++----------------------
1 file changed, 61 insertions(+), 43 deletions(-)
(limited to 'type/Base.class.php')
diff --git a/type/Base.class.php b/type/Base.class.php
index 1f42f4f..72ce437 100644
--- a/type/Base.class.php
+++ b/type/Base.class.php
@@ -36,8 +36,14 @@ class Type_Base {
function __construct($config, $_get) {
$this->datadir = $config['datadir'];
$this->rrdtool = $config['rrdtool'];
- if (!empty($config['rrdtool_opts']))
- $this->rrdtool_opts[] = $config['rrdtool_opts'];
+ if (!empty($config['rrdtool_opts'])) {
+ if (is_array($config['rrdtool_opts'])) {
+ $this->rrdtool_opts = $config['rrdtool_opts'];
+ } else {
+ $this->rrdtool_opts = explode(' ',
+ $config['rrdtool_opts']);
+ }
+ }
$this->cache = $config['cache'];
$this->parse_get($_get);
$this->rrd_title = sprintf(
@@ -200,78 +206,90 @@ class Type_Base {
$this->rainbow_colors();
$this->colors = $colors + $this->colors;
- $graphdata = $this->rrd_gen_graph();
+ $graphoptions = $this->rrd_gen_graph();
+ # $shellcmd contains escaped rrdtool arguments
+ $shellcmd = array();
+ foreach ($graphoptions as $arg)
+ $shellcmd[] = escapeshellarg($arg);
$style = $debug !== false ? $debug : $this->graph_type;
switch ($style) {
case 'cmd':
print '
';
- foreach ($graphdata as $d) {
+ foreach ($shellcmd as $d) {
printf("%s \\\n", htmlentities($d));
}
print '
';
break;
case 'canvas':
- printf('