Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Reject directory traversal in store report processor

commit 554eefc55f57ed2b76e5ee04d8f194d36f6ee67f 1 parent fe53647
Patrick Carlisle authored June 28, 2012
10  lib/puppet/reports/store.rb
... ...
@@ -1,5 +1,7 @@
1 1
 require 'puppet'
2 2
 
  3
+SEPARATOR = [Regexp.escape(File::SEPARATOR.to_s), Regexp.escape(File::ALT_SEPARATOR.to_s)].join
  4
+
3 5
 Puppet::Reports.register_report(:store) do
4 6
   desc "Store the yaml report on disk.  Each host sends its report as a YAML dump
5 7
     and this just stores the file on disk, in the `reportdir` directory.
@@ -11,9 +13,11 @@
11 13
   def process
12 14
     # We don't want any tracking back in the fs.  Unlikely, but there
13 15
     # you go.
14  
-    client = self.host.gsub("..",".")
  16
+    if host =~ Regexp.union(/[#{SEPARATOR}]/, /\A\.\.?\Z/)
  17
+      raise ArgumentError, "Invalid node name #{host.inspect}"
  18
+    end
15 19
 
16  
-    dir = File.join(Puppet[:reportdir], client)
  20
+    dir = File.join(Puppet[:reportdir], host)
17 21
 
18 22
     if ! FileTest.exists?(dir)
19 23
       FileUtils.mkdir_p(dir)
@@ -35,7 +39,7 @@ def process
35 39
       end
36 40
     rescue => detail
37 41
       puts detail.backtrace if Puppet[:trace]
38  
-      Puppet.warning "Could not write report for #{client} at #{file}: #{detail}"
  42
+      Puppet.warning "Could not write report for #{host} at #{file}: #{detail}"
39 43
     end
40 44
 
41 45
     # Only testing cares about the return value
14  spec/unit/reports/store_spec.rb
@@ -27,5 +27,19 @@
27 27
 
28 28
       File.read(File.join(Puppet[:reportdir], @report.host, "201101061200.yaml")).should == @report.to_yaml
29 29
     end
  30
+
  31
+    ['..', 'hello/', '/hello', 'he/llo', 'hello/..', '.'].each do |node|
  32
+      it "rejects #{node.inspect}" do
  33
+        @report.host = node
  34
+        expect { @report.process }.to raise_error(ArgumentError, /Invalid node/)
  35
+      end
  36
+    end
  37
+
  38
+    ['.hello', 'hello.', '..hi', 'hi..'].each do |node|
  39
+      it "accepts #{node.inspect}" do
  40
+        @report.host = node
  41
+        @report.process
  42
+      end
  43
+    end
30 44
   end
31 45
 end

0 notes on commit 554eefc

Please sign in to comment.
Something went wrong with that request. Please try again.