brakeman-min 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/brakeman CHANGED
@@ -34,6 +34,10 @@ OptionParser.new do |opts|
34
34
  options[:ignore_model_output] = true
35
35
  end
36
36
 
37
+ opts.on "-e", "--escape-html", "Escape HTML by default" do
38
+ options[:escape_html] = true
39
+ end
40
+
37
41
  opts.on "-r", "--report-direct", "Only report direct use of untrusted data" do |option|
38
42
  options[:check_arguments] = !option
39
43
  end
@@ -30,6 +30,8 @@ class CheckCrossSiteScripting < BaseCheck
30
30
 
31
31
  HAML_HELPERS = Sexp.new(:colon2, Sexp.new(:const, :Haml), :Helpers)
32
32
 
33
+ XML_HELPER = Sexp.new(:colon2, Sexp.new(:const, :Erubis), :XmlHelper)
34
+
33
35
  URI = Sexp.new(:const, :URI)
34
36
 
35
37
  CGI = Sexp.new(:const, :CGI)
@@ -48,7 +50,7 @@ class CheckCrossSiteScripting < BaseCheck
48
50
  @current_template = template
49
51
 
50
52
  template[:outputs].each do |out|
51
- type, match = has_immediate_user_input?(out[1])
53
+ type, match = (out[0] == :output and has_immediate_user_input?(out[1]))
52
54
  if type and not duplicate? out
53
55
  add_result out
54
56
  case type
@@ -102,6 +104,16 @@ class CheckCrossSiteScripting < BaseCheck
102
104
  process exp[1].dup
103
105
  end
104
106
 
107
+ #Look for calls to raw()
108
+ #Otherwise, ignore
109
+ def process_escaped_output exp
110
+ if exp[1].node_type == :call and exp[1][2] == :raw
111
+ process_output exp
112
+ else
113
+ exp
114
+ end
115
+ end
116
+
105
117
  #Check a call for user input
106
118
  #
107
119
  #
@@ -154,6 +166,7 @@ class CheckCrossSiteScripting < BaseCheck
154
166
  (@matched == :model and IGNORE_MODEL_METHODS.include? method) or
155
167
  (target == HAML_HELPERS and method == :html_escape) or
156
168
  ((target == URI or target == CGI) and method == :escape) or
169
+ (target == XML_HELPER and method == :escape_xml) or
157
170
  (target == FORM_BUILDER and IGNORE_METHODS.include? method) or
158
171
  (method.to_s[-1,1] == "?")
159
172
 
@@ -163,7 +176,6 @@ class CheckCrossSiteScripting < BaseCheck
163
176
 
164
177
  @matched = :model
165
178
  elsif @inspect_arguments and (ALL_PARAMETERS.include?(exp) or params? exp)
166
-
167
179
  @matched = :params
168
180
  elsif @inspect_arguments
169
181
  process args
data/lib/processor.rb CHANGED
@@ -50,6 +50,8 @@ class Processor
50
50
  result = ErbTemplateProcessor.new(@tracker, name, called_from, file_name).process src
51
51
  when :haml
52
52
  result = HamlTemplateProcessor.new(@tracker, name, called_from, file_name).process src
53
+ when :erubis
54
+ result = ErubisTemplateProcessor.new(@tracker, name, called_from, file_name).process src
53
55
  else
54
56
  abort "Unknown template type: #{type} (#{name})"
55
57
  end
@@ -2,6 +2,7 @@ require 'processors/template_processor'
2
2
 
3
3
  #Processes ERB templates using Erubis instead of erb.
4
4
  class ErubisTemplateProcessor < TemplateProcessor
5
+
5
6
 
6
7
  #s(:call, TARGET, :method, s(:arglist))
7
8
  def process_call exp
@@ -10,10 +11,10 @@ class ErubisTemplateProcessor < TemplateProcessor
10
11
  target = process target
11
12
  end
12
13
  method = exp[2]
13
-
14
+
14
15
  #_buf is the default output variable for Erubis
15
- if target and target[1] == :_buf
16
- if method == :<<
16
+ if target and (target[1] == :_buf or target[1] == :output_buffer)
17
+ if method == :<< or method == :safe_concat
17
18
  args = exp[3][1] = process(exp[3][1])
18
19
 
19
20
  if args.node_type == :call and args[2] == :to_s #just calling to_s on inner code
@@ -59,4 +60,26 @@ class ErubisTemplateProcessor < TemplateProcessor
59
60
  block.line(exp.line)
60
61
  block
61
62
  end
63
+
64
+ #Look for assignments to output buffer
65
+ def process_attrasgn exp
66
+ if exp[1].node_type == :ivar and exp[1][1] == :@output_buffer
67
+ if exp[2] == :append= or exp[2] == :safe_append=
68
+ args = exp[3][1] = process(exp[3][1])
69
+
70
+ if args.node_type == :str
71
+ ignore
72
+ else
73
+ s = Sexp.new :escaped_output, args
74
+ s.line(exp.line)
75
+ @current_template[:outputs] << s
76
+ s
77
+ end
78
+ else
79
+ ignore
80
+ end
81
+ else
82
+ super
83
+ end
84
+ end
62
85
  end
@@ -153,6 +153,23 @@ class OutputProcessor < Ruby2Ruby
153
153
  out
154
154
  end
155
155
 
156
+ def process_escaped_output exp
157
+ out = if exp[0].node_type == :str
158
+ ""
159
+ else
160
+ res = process exp[0]
161
+
162
+ if res == ""
163
+ ""
164
+ else
165
+ "[Escaped Output] #{res}"
166
+ end
167
+ end
168
+ exp.clear
169
+ out
170
+ end
171
+
172
+
156
173
  def process_format exp
157
174
  out = if exp[0].node_type == :str or exp[0].node_type == :ignore
158
175
  ""
data/lib/scanner.rb CHANGED
@@ -53,7 +53,9 @@ class Scanner
53
53
  @processor.process_config(RubyParser.new.parse(File.read("#@path/config/gems.rb")))
54
54
  end
55
55
 
56
- if File.exists? "#@path/vendor/plugins/rails_xss" or OPTIONS[:rails3]
56
+ if File.exists? "#@path/vendor/plugins/rails_xss" or
57
+ OPTIONS[:rails3] or OPTIONS[:escape_html] or
58
+ (File.exists? "#@path/Gemfile" and File.read("#@path/Gemfile").include? "rails_xss")
57
59
  tracker.config[:escape_html] = true
58
60
  warn "[Notice] Escaping HTML by default"
59
61
  end
@@ -139,10 +141,17 @@ class Scanner
139
141
  if type == :erb
140
142
  if tracker.config[:escape_html]
141
143
  initialize_erubis unless @initialized_erubis
142
- src = RailsXSSErubis.new(File.read(f)).src
144
+ type = :erubis
145
+ if OPTIONS[:rails3]
146
+ src = RailsXSSErubis.new(File.read(f)).src
147
+ else
148
+ src = ErubisEscape.new(File.read(f)).src
149
+ end
143
150
  elsif tracker.config[:erubis]
144
151
  initialize_erubis unless @initialized_erubis
145
152
  src = ScannerErubis.new(File.read(f)).src
153
+ type = :erubis
154
+ src = ScannerErubis.new(File.read(f)).src
146
155
  else
147
156
  src = ERB.new(File.read(f), nil, "-").src
148
157
  end
@@ -6,34 +6,49 @@ rescue LoadError => e
6
6
  exit!
7
7
  end
8
8
 
9
- #This is from the rails_xss plugin,
10
- #except we don't care about plain text.
9
+ #This is from Rails 3 version of the Erubis handler
11
10
  class RailsXSSErubis < ::Erubis::Eruby
12
11
  include Erubis::NoTextEnhancer
13
12
 
14
13
  #Initializes output buffer.
15
14
  def add_preamble(src)
16
- src << "@output_buffer = ActionView::SafeBuffer.new;\n"
15
+ # src << "_buf = ActionView::SafeBuffer.new;\n"
17
16
  end
18
17
 
19
18
  #This does nothing.
20
19
  def add_text(src, text)
21
- # src << "@output_buffer << ('" << escape_text(text) << "'.html_safe!);"
20
+ # src << "@output_buffer << ('" << escape_text(text) << "'.html_safe!);"
22
21
  end
23
22
 
24
- #Add an expression to the output buffer _without_ escaping.
23
+ BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
24
+
25
25
  def add_expr_literal(src, code)
26
- src << '@output_buffer << ((' << code << ').to_s);'
26
+ if code =~ BLOCK_EXPR
27
+ src << '@output_buffer.append= ' << code
28
+ else
29
+ src << '@output_buffer.append= (' << code << ');'
30
+ end
31
+ end
32
+
33
+ def add_stmt(src, code)
34
+ if code =~ BLOCK_EXPR
35
+ src << '@output_buffer.append_if_string= ' << code
36
+ else
37
+ super
38
+ end
27
39
  end
28
40
 
29
- #Add an expression to the output buffer after escaping it.
30
41
  def add_expr_escaped(src, code)
31
- src << '@output_buffer << ' << escaped_expr(code) << ';'
42
+ if code =~ BLOCK_EXPR
43
+ src << "@output_buffer.safe_append= " << code
44
+ else
45
+ src << "@output_buffer.safe_concat(" << code << ");"
46
+ end
32
47
  end
33
48
 
34
49
  #Add code to output buffer.
35
50
  def add_postamble(src)
36
- src << '@output_buffer.to_s'
51
+ # src << '_buf.to_s'
37
52
  end
38
53
  end
39
54
 
@@ -41,3 +56,8 @@ end
41
56
  class ScannerErubis < Erubis::Eruby
42
57
  include Erubis::NoTextEnhancer
43
58
  end
59
+
60
+ class ErubisEscape < ScannerErubis
61
+ include Erubis::EscapeEnhancer
62
+ end
63
+
data/lib/version.rb CHANGED
@@ -1 +1 @@
1
- Version = "0.3.2"
1
+ Version = "0.4.0"
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
8
- - 2
9
- version: 0.3.2
7
+ - 4
8
+ - 0
9
+ version: 0.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Justin Collins
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-05-12 00:00:00 -07:00
17
+ date: 2011-05-18 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency