Ticket #1189 (new enhancement)

Opened 4 months ago

[PATCH] Sanitise attributes and values

Reported by: cbiedl Assigned to: nobody
Priority: normal Milestone: Munin 2.0
Component: plugins Version: 2.0-beta4
Severity: normal Keywords:
Cc:

Description

Hello,

At the moment, munin happily eats virtually everything a plugin sends as long as it fits the "attribute value" or "field.attribute value" format.

To reduce a possible impact, I'd like to propose to sanitize that data in the future, and at an rather early stage in the processing. For a beginning, the patch below invalidates backslash-anything sequences by replacing it with an underline character. Only exception: backslash-backslash which in converted into a single backslash. See ticket 1187 where I proposed that as a way to have a backslash character in a label.

For the records, the worst things I've encountered so far is graph are not drawn since rrdgraph got confused. Having a graph with some information altered is much more helpful for debugging.

Please think about that before applying. This a change in the munin protocol that should not do harm. But I wouldn't be that sure about it.

Cheers,

Christoph

--- /usr/share/perl5/Munin/Master/Node.pm.orig  2012-01-18 08:08:21.000000000 +0100
+++ /usr/share/perl5/Munin/Master/Node.pm       2012-01-21 20:42:43.657949903 +0100
@@ -314,7 +314,7 @@
            my $label = $self->_sanitise_fieldname($1);
 
            # add to config if not already here
-           push @{$global_config->{$service}}, [$label, $2]
+           push @{$global_config->{$service}}, [$label, $self->_sanitise_attribute($2)]
                unless grep { $_->[0] eq $label }  @{$global_config->{$service}};
             DEBUG "[CONFIG graph global $plugin] $service->$label = $2" if $debug;
         } elsif ($line =~ m{\A ([^\.]+)\.value \s+ (.+?) \s* $}xms) {
@@ -343,6 +343,8 @@
            
             my ($ds_name, $ds_var, $ds_val) = ($1, $2, $3);
             $ds_name = $self->_sanitise_fieldname($ds_name);
+           $ds_var = $self->_sanitise_attribute($ds_var);
+           $ds_val = $self->_sanitise_attribute($ds_val);
             $data_source_config->{$service}{$ds_name} ||= {};
             $data_source_config->{$service}{$ds_name}{$ds_var} = $ds_val;
             DEBUG "[CONFIG dataseries $plugin] $service->$ds_name.$ds_var = $ds_val" if $debug;
@@ -559,6 +561,15 @@
     return $name;
 }
 
+
+sub _sanitise_attribute {
+    my ($self, $name) = @_;
+
+    $name =~ s/\\(.|$)/($1 || '') eq "\\" ? "\\" : '_'/ge;
+    
+    return $name;
+}
+
 
 sub _node_write_single {
     my ($self, $text) = @_;