brakeman 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -41,6 +41,10 @@ To specify an output file for the results:
41
41
 
42
42
  The output format is determined by the file extension or by using the `-f` option. Current options are: `text`, `html`, `tabs`, `json` and `csv`.
43
43
 
44
+ Multiple output files can be specified:
45
+
46
+ brakeman -o output.html -o output.json
47
+
44
48
  To suppress informational warnings and just output the report:
45
49
 
46
50
  brakeman -q
@@ -27,8 +27,8 @@ module Brakeman
27
27
  # * :ignore_model_output - consider models safe (default: false)
28
28
  # * :message_limit - limit length of messages
29
29
  # * :min_confidence - minimum confidence (0-2, 0 is highest)
30
- # * :output_file - file for output
31
- # * :output_format - format for output (:to_s, :to_tabs, :to_csv, :to_html)
30
+ # * :output_files - files for output
31
+ # * :output_formats - formats for output (:to_s, :to_tabs, :to_csv, :to_html)
32
32
  # * :parallel_checks - run checks in parallel (default: true)
33
33
  # * :print_report - if no output file specified, print to stdout (default: false)
34
34
  # * :quiet - suppress most messages (default: true)
@@ -65,7 +65,7 @@ module Brakeman
65
65
 
66
66
  options = load_options(options[:config_file]).merge! options
67
67
  options = get_defaults.merge! options
68
- options[:output_format] = get_output_format options
68
+ options[:output_formats] = get_output_formats options
69
69
 
70
70
  app_path = options[:app_path]
71
71
 
@@ -124,39 +124,47 @@ module Brakeman
124
124
  }
125
125
  end
126
126
 
127
- #Determine output format based on options[:output_format]
128
- #or options[:output_file]
129
- def self.get_output_format options
127
+ #Determine output formats based on options[:output_formats]
128
+ #or options[:output_files]
129
+ def self.get_output_formats options
130
130
  #Set output format
131
+ if options[:output_format] && options[:output_files] && options[:output_files].size > 1
132
+ raise ArgumentError, "Cannot specify output format if multiple output files specified"
133
+ end
131
134
  if options[:output_format]
132
- case options[:output_format]
133
- when :html, :to_html
134
- :to_html
135
- when :csv, :to_csv
136
- :to_csv
137
- when :pdf, :to_pdf
138
- :to_pdf
139
- when :tabs, :to_tabs
140
- :to_tabs
141
- when :json, :to_json
142
- :to_json
143
- else
144
- :to_s
145
- end
135
+ [
136
+ case options[:output_format]
137
+ when :html, :to_html
138
+ :to_html
139
+ when :csv, :to_csv
140
+ :to_csv
141
+ when :pdf, :to_pdf
142
+ :to_pdf
143
+ when :tabs, :to_tabs
144
+ :to_tabs
145
+ when :json, :to_json
146
+ :to_json
147
+ else
148
+ :to_s
149
+ end
150
+ ]
146
151
  else
147
- case options[:output_file]
148
- when /\.html$/i
149
- :to_html
150
- when /\.csv$/i
151
- :to_csv
152
- when /\.pdf$/i
153
- :to_pdf
154
- when /\.tabs$/i
155
- :to_tabs
156
- when /\.json$/i
157
- :to_json
158
- else
159
- :to_s
152
+ return [:to_s] unless options[:output_files]
153
+ options[:output_files].map do |output_file|
154
+ case output_file
155
+ when /\.html$/i
156
+ :to_html
157
+ when /\.csv$/i
158
+ :to_csv
159
+ when /\.pdf$/i
160
+ :to_pdf
161
+ when /\.tabs$/i
162
+ :to_tabs
163
+ when /\.json$/i
164
+ :to_json
165
+ else
166
+ :to_s
167
+ end
160
168
  end
161
169
  end
162
170
  end
@@ -253,17 +261,21 @@ module Brakeman
253
261
  end
254
262
  tracker.run_checks
255
263
 
256
- if options[:output_file]
264
+ if options[:output_files]
257
265
  notify "Generating report..."
258
266
 
259
- File.open options[:output_file], "w" do |f|
260
- f.puts tracker.report.send(options[:output_format])
267
+ options[:output_files].each_with_index do |output_file, idx|
268
+ File.open output_file, "w" do |f|
269
+ f.write tracker.report.send(options[:output_formats][idx])
270
+ end
271
+ notify "Report saved in '#{output_file}'"
261
272
  end
262
- notify "Report saved in '#{options[:output_file]}'"
263
273
  elsif options[:print_report]
264
274
  notify "Generating report..."
265
275
 
266
- puts tracker.report.send(options[:output_format])
276
+ options[:output_formats].each do |output_format|
277
+ puts tracker.report.send(output_format)
278
+ end
267
279
  end
268
280
 
269
281
  tracker
@@ -0,0 +1,9 @@
1
+ namespace :brakeman do
2
+
3
+ desc "Run Brakeman"
4
+ task :run, :output_file do |t, args|
5
+ require 'brakeman'
6
+
7
+ Brakeman.run :app_path => ".", :output_file => args[:output_file], :print_report => true
8
+ end
9
+ end
@@ -18,9 +18,9 @@ class Brakeman::CheckEvaluation < Brakeman::BaseCheck
18
18
  end
19
19
  end
20
20
 
21
- #Warns if result includes user input
21
+ #Warns if eval includes user input
22
22
  def process_result result
23
- if include_user_input? result[:call]
23
+ if include_user_input? result[:call][-1]
24
24
  warn :result => result,
25
25
  :warning_type => "Dangerous Eval",
26
26
  :message => "User input in eval",
@@ -0,0 +1,38 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ #Checks if user supplied data is passed to send
4
+ class Brakeman::CheckSend < Brakeman::BaseCheck
5
+ Brakeman::Checks.add self
6
+
7
+ @description = "Check for unsafe use of Object#send"
8
+
9
+ def run_check
10
+ Brakeman.debug("Finding instances of #send")
11
+ calls = tracker.find_call :method => :send
12
+
13
+ calls.each do |call|
14
+ process_result call
15
+ end
16
+ end
17
+
18
+ def process_result result
19
+ args = process result[:call][3]
20
+ target = process result[:call][1]
21
+
22
+ if has_immediate_user_input? args[1]
23
+ warn :result => result,
24
+ :warning_type => "Dangerous Send",
25
+ :message => "User controlled method execution",
26
+ :code => result[:call],
27
+ :confidence => CONFIDENCE[:high]
28
+ end
29
+
30
+ if has_immediate_user_input?(target)
31
+ warn :result => result,
32
+ :warning_type => "Dangerous Send",
33
+ :message => "User defined target of method invocation",
34
+ :code => result[:call],
35
+ :confidence => CONFIDENCE[:med]
36
+ end
37
+ end
38
+ end
@@ -130,7 +130,7 @@ module Brakeman::Options
130
130
  opts.on "-f",
131
131
  "--format TYPE",
132
132
  [:pdf, :text, :html, :csv, :tabs, :json],
133
- "Specify output format. Default is text" do |type|
133
+ "Specify output formats. Default is text" do |type|
134
134
 
135
135
  type = "s" if type == :text
136
136
  options[:output_format] = ("to_" << type.to_s).to_sym
@@ -152,8 +152,9 @@ module Brakeman::Options
152
152
  options[:message_limit] = limit.to_i
153
153
  end
154
154
 
155
- opts.on "-o", "--output FILE", "Specify file for output. Defaults to stdout" do |file|
156
- options[:output_file] = file
155
+ opts.on "-o", "--output FILE", "Specify files for output. Defaults to stdout. Multiple '-o's allowed" do |file|
156
+ options[:output_files] ||= []
157
+ options[:output_files].push(file)
157
158
  end
158
159
 
159
160
  opts.on "--separate-models", "Warn on each model without attr_accessible" do
@@ -0,0 +1,4 @@
1
+ #Erubis processor which ignores any output which is plain text.
2
+ class Brakeman::ScannerErubis < Erubis::Eruby
3
+ include Erubis::NoTextEnhancer
4
+ end
@@ -0,0 +1,46 @@
1
+ #This is from the rails_xss plugin for Rails 2
2
+ class Brakeman::Rails2XSSPluginErubis < ::Erubis::Eruby
3
+ def add_preamble(src)
4
+ #src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
5
+ end
6
+
7
+ #This is different from rails_xss - fixes some line number issues
8
+ def add_text(src, text)
9
+ if text == "\n"
10
+ src << "\n"
11
+ elsif text.include? "\n"
12
+ lines = text.split("\n")
13
+ if text.match(/\n\z/)
14
+ lines.each do |line|
15
+ src << "@output_buffer.safe_concat('" << escape_text(line) << "');\n"
16
+ end
17
+ else
18
+ lines[0..-2].each do |line|
19
+ src << "@output_buffer.safe_concat('" << escape_text(line) << "');\n"
20
+ end
21
+
22
+ src << "@output_buffer.safe_concat('" << escape_text(lines.last) << "');"
23
+ end
24
+ else
25
+ src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
26
+ end
27
+ end
28
+
29
+ BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
30
+
31
+ def add_expr_literal(src, code)
32
+ if code =~ BLOCK_EXPR
33
+ src << "@output_buffer.safe_concat((" << $1 << ").to_s);"
34
+ else
35
+ src << '@output_buffer << ((' << code << ').to_s);'
36
+ end
37
+ end
38
+
39
+ def add_expr_escaped(src, code)
40
+ src << '@output_buffer << ' << escaped_expr(code) << ';'
41
+ end
42
+
43
+ def add_postamble(src)
44
+ #src << '@output_buffer.to_s'
45
+ end
46
+ end
@@ -0,0 +1,60 @@
1
+ #This is from Rails 3 version of the Erubis handler
2
+ class Brakeman::Rails3Erubis < ::Erubis::Eruby
3
+
4
+ def add_preamble(src)
5
+ # src << "_buf = ActionView::SafeBuffer.new;\n"
6
+ end
7
+
8
+ #This is different from Rails 3 - fixes some line number issues
9
+ def add_text(src, text)
10
+ if text == "\n"
11
+ src << "\n"
12
+ elsif text.include? "\n"
13
+ lines = text.split("\n")
14
+ if text.match(/\n\z/)
15
+ lines.each do |line|
16
+ src << "@output_buffer << ('" << escape_text(line) << "'.html_safe!);\n"
17
+ end
18
+ else
19
+ lines[0..-2].each do |line|
20
+ src << "@output_buffer << ('" << escape_text(line) << "'.html_safe!);\n"
21
+ end
22
+
23
+ src << "@output_buffer << ('" << escape_text(lines.last) << "'.html_safe!);"
24
+ end
25
+ else
26
+ src << "@output_buffer << ('" << escape_text(text) << "'.html_safe!);"
27
+ end
28
+ end
29
+
30
+ BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
31
+
32
+ def add_expr_literal(src, code)
33
+ if code =~ BLOCK_EXPR
34
+ src << '@output_buffer.append= ' << code
35
+ else
36
+ src << '@output_buffer.append= (' << code << ');'
37
+ end
38
+ end
39
+
40
+ def add_stmt(src, code)
41
+ if code =~ BLOCK_EXPR
42
+ src << '@output_buffer.append_if_string= ' << code
43
+ else
44
+ super
45
+ end
46
+ end
47
+
48
+ def add_expr_escaped(src, code)
49
+ if code =~ BLOCK_EXPR
50
+ src << "@output_buffer.safe_append= " << code
51
+ else
52
+ src << "@output_buffer.safe_concat(" << code << ");"
53
+ end
54
+ end
55
+
56
+ #Add code to output buffer.
57
+ def add_postamble(src)
58
+ # src << '_buf.to_s'
59
+ end
60
+ end
@@ -40,8 +40,8 @@ module Brakeman
40
40
 
41
41
  #Process variable aliasing in controller source and save it in the
42
42
  #tracker.
43
- def process_controller_alias src, only_method = nil
44
- ControllerAliasProcessor.new(@tracker, only_method).process src
43
+ def process_controller_alias name, src, only_method = nil
44
+ ControllerAliasProcessor.new(@tracker, only_method).process_controller name, src
45
45
  end
46
46
 
47
47
  #Process a model source
@@ -492,12 +492,25 @@ class Brakeman::AliasProcessor < SexpProcessor
492
492
 
493
493
  #Returns a new SexpProcessor::Environment containing only instance variables.
494
494
  #This is useful, for example, when processing views.
495
- def only_ivars
495
+ def only_ivars include_request_vars = false
496
496
  res = SexpProcessor::Environment.new
497
- env.all.each do |k, v|
498
- #TODO Why would this have nil values?
499
- res[k] = v.dup if k.node_type == :ivar and not v.nil?
497
+
498
+ if include_request_vars
499
+ env.all.each do |k, v|
500
+ #TODO Why would this have nil values?
501
+ if (k.node_type == :ivar or request_value? k) and not v.nil?
502
+ res[k] = v.dup
503
+ end
504
+ end
505
+ else
506
+ env.all.each do |k, v|
507
+ #TODO Why would this have nil values?
508
+ if k.node_type == :ivar and not v.nil?
509
+ res[k] = v.dup
510
+ end
511
+ end
500
512
  end
513
+
501
514
  res
502
515
  end
503
516
 
@@ -32,14 +32,6 @@ class Brakeman::BaseProcessor < SexpProcessor
32
32
  exp
33
33
  end
34
34
 
35
- def process_module exp
36
- current_module = @current_module
37
- @current_module = class_name exp[1]
38
- process exp[2]
39
- @current_module = current_module
40
- exp
41
- end
42
-
43
35
  #Process a new scope. Removes expressions that are set to nil.
44
36
  def process_scope exp
45
37
  exp = exp.dup
@@ -210,9 +202,14 @@ class Brakeman::BaseProcessor < SexpProcessor
210
202
  exp
211
203
  end
212
204
 
205
+ #Convenience method for `make_render exp, true`
206
+ def make_render_in_view exp
207
+ make_render exp, true
208
+ end
209
+
213
210
  #Generates :render node from call to render.
214
- def make_render exp
215
- render_type, value, rest = find_render_type exp[3]
211
+ def make_render exp, in_view = false
212
+ render_type, value, rest = find_render_type exp[3], in_view
216
213
  rest = process rest
217
214
  result = Sexp.new(:render, render_type, value, rest)
218
215
  result.line(exp.line)
@@ -222,9 +219,11 @@ class Brakeman::BaseProcessor < SexpProcessor
222
219
  #Determines the type of a call to render.
223
220
  #
224
221
  #Possible types are:
225
- #:action, :default :file, :inline, :js, :json, :nothing, :partial,
222
+ #:action, :default, :file, :inline, :js, :json, :nothing, :partial,
226
223
  #:template, :text, :update, :xml
227
- def find_render_type args
224
+ #
225
+ #And also :layout for inside templates
226
+ def find_render_type args, in_view = false
228
227
  rest = Sexp.new(:hash)
229
228
  type = nil
230
229
  value = nil
@@ -252,10 +251,18 @@ class Brakeman::BaseProcessor < SexpProcessor
252
251
  value = args[1]
253
252
  end
254
253
 
254
+ types_in_hash = Set[:action, :file, :inline, :js, :json, :nothing, :partial, :text, :update, :xml]
255
+
256
+ #render :layout => "blah" means something else when in a template
257
+ if in_view
258
+ types_in_hash << :layout
259
+ end
260
+
261
+ #Look for "type" of render in options hash
262
+ #For example, render :file => "blah"
255
263
  if hash? args[-1]
256
264
  hash_iterate(args[-1]) do |key, val|
257
- case key[1]
258
- when :action, :file, :inline, :js, :json, :nothing, :partial, :text, :update, :xml
265
+ if types_in_hash.include? key[1]
259
266
  type = key[1]
260
267
  value = val
261
268
  else
@@ -17,11 +17,23 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
17
17
  @current_class = @current_module = @current_method = nil
18
18
  end
19
19
 
20
+ def process_controller name, src
21
+ if not node_type? src, :class
22
+ Brakeman.debug "#{name} is not a class, it's a #{src.node_type}"
23
+ return
24
+ else
25
+ @current_class = name
26
+ process_default src
27
+ end
28
+ end
29
+
20
30
  #Processes a class which is probably a controller.
31
+ #(This method should be retired - only classes should ever be processed
32
+ # and @current_module will never be set, leading to inaccurate class names)
21
33
  def process_class exp
22
34
  @current_class = class_name(exp[1])
23
35
  if @current_module
24
- @current_class = (@current_module + "::" + @current_class.to_s).to_sym
36
+ @current_class = ("#@current_module::#@current_class").to_sym
25
37
  end
26
38
 
27
39
  process_default exp
@@ -101,7 +113,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
101
113
  processor = Brakeman::AliasProcessor.new @tracker
102
114
  processor.process_safely(method[3])
103
115
 
104
- ivars = processor.only_ivars.all
116
+ ivars = processor.only_ivars(:include_request_vars).all
105
117
 
106
118
  @tracker.filter_cache[[filter[:controller], name]] = ivars
107
119
 
@@ -130,7 +130,13 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
130
130
  name = exp[2]
131
131
 
132
132
  if exp[1].node_type == :self
133
- target = @controller[:name]
133
+ if @controller
134
+ target = @controller[:name]
135
+ elsif @current_module
136
+ target = @current_module
137
+ else
138
+ target = nil
139
+ end
134
140
  else
135
141
  target = class_name exp[1]
136
142
  end
@@ -44,7 +44,7 @@ class Brakeman::ErbTemplateProcessor < Brakeman::TemplateProcessor
44
44
  end
45
45
  elsif target == nil and method == :render
46
46
  exp[3] = process(exp[3])
47
- make_render exp
47
+ make_render_in_view exp
48
48
  else
49
49
  args = exp[3] = process(exp[3])
50
50
  call = Sexp.new :call, target, method, args
@@ -41,7 +41,7 @@ class Brakeman::ErubisTemplateProcessor < Brakeman::TemplateProcessor
41
41
  end
42
42
  elsif target == nil and method == :render
43
43
  exp[3] = process exp[3]
44
- make_render exp
44
+ make_render_in_view exp
45
45
  else
46
46
  args = exp[3] = process(exp[3])
47
47
  call = Sexp.new :call, target, method, args
@@ -92,7 +92,7 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
92
92
  elsif target == nil and method == :render
93
93
  #Process call to render()
94
94
  exp[3] = process exp[3]
95
- make_render exp
95
+ make_render_in_view exp
96
96
  else
97
97
  args = process exp[3]
98
98
  call = Sexp.new :call, target, method, args
@@ -3,9 +3,19 @@ module Brakeman::ProcessorHelper
3
3
 
4
4
  #Sets the current module.
5
5
  def process_module exp
6
- @current_module = class_name(exp[1]).to_s
7
- process exp[2]
8
- @current_module = nil
6
+ module_name = class_name(exp[1]).to_s
7
+ prev_module = @current_module
8
+
9
+ if prev_module
10
+ @current_module = "#{prev_module}::#{module_name}"
11
+ else
12
+ @current_module = module_name
13
+ end
14
+
15
+ process exp[2]
16
+
17
+ @current_module = prev_module
18
+
9
19
  exp
10
20
  end
11
21
 
@@ -11,8 +11,13 @@ module Brakeman::RenderHelper
11
11
  when :action
12
12
  process_action exp[2][1], exp[3]
13
13
  when :default
14
- process_template template_name, exp[3]
15
- when :partial
14
+ begin
15
+ process_template template_name, exp[3]
16
+ rescue ArgumentError => e
17
+ Brakeman.debug "Problem processing render: #{exp}"
18
+ raise e
19
+ end
20
+ when :partial, :layout
16
21
  process_partial exp[2], exp[3]
17
22
  when :nothing
18
23
  end
@@ -58,7 +63,7 @@ module Brakeman::RenderHelper
58
63
  return
59
64
  end
60
65
 
61
- template_env = only_ivars
66
+ template_env = only_ivars(:include_request_vars)
62
67
 
63
68
  #Hash the environment and the source of the template to avoid
64
69
  #pointlessly processing templates, which can become prohibitively
@@ -117,7 +122,7 @@ module Brakeman::RenderHelper
117
122
  #Run source through AliasProcessor with instance variables from the
118
123
  #current environment.
119
124
  #TODO: Add in :locals => { ... } to environment
120
- src = Brakeman::TemplateAliasProcessor.new(@tracker, template).process_safely(template[:src], template_env)
125
+ src = Brakeman::TemplateAliasProcessor.new(@tracker, template, called_from).process_safely(template[:src], template_env)
121
126
 
122
127
  #Run alias-processed src through the template processor to pull out
123
128
  #information and outputs.
@@ -9,14 +9,19 @@ class Brakeman::TemplateAliasProcessor < Brakeman::AliasProcessor
9
9
 
10
10
  FORM_METHODS = Set[:form_for, :remote_form_for, :form_remote_for]
11
11
 
12
- def initialize tracker, template
13
- super()
14
- @tracker = tracker
12
+ def initialize tracker, template, called_from = nil
13
+ super tracker
15
14
  @template = template
15
+ @called_from = called_from
16
16
  end
17
17
 
18
18
  #Process template
19
19
  def process_template name, args
20
+ if @called_from and @called_from.match(/Template:#{Regexp.escape name}$/)
21
+ Brakeman.debug "Skipping circular render from #{@template[:name]} to #{name}"
22
+ return
23
+ end
24
+
20
25
  super name, args, "Template:#{@template[:name]}"
21
26
  end
22
27
 
@@ -117,6 +117,8 @@ class Brakeman::Rescanner < Brakeman::Scanner
117
117
  end
118
118
 
119
119
  def rescan_template path
120
+ return unless path.match KNOWN_TEMPLATE_EXTENSIONS
121
+
120
122
  template_name = template_path_to_name(path)
121
123
 
122
124
  tracker.reset_template template_name
@@ -13,26 +13,21 @@ begin
13
13
  require 'erb'
14
14
  require 'erubis'
15
15
  require 'brakeman/processor'
16
+ require 'brakeman/parsers/rails2_erubis'
17
+ require 'brakeman/parsers/rails2_xss_plugin_erubis'
18
+ require 'brakeman/parsers/rails3_erubis'
16
19
  rescue LoadError => e
17
20
  $stderr.puts e.message
18
21
  $stderr.puts "Please install the appropriate dependency."
19
22
  exit
20
23
  end
21
24
 
22
- #Erubis processor which ignores any output which is plain text.
23
- class Brakeman::ScannerErubis < Erubis::Eruby
24
- include Erubis::NoTextEnhancer
25
- end
26
-
27
- class Brakeman::ErubisEscape < Brakeman::ScannerErubis
28
- include Erubis::EscapeEnhancer
29
- end
30
-
31
25
  #Scans the Rails application.
32
26
  class Brakeman::Scanner
33
27
  attr_reader :options
34
28
 
35
29
  RUBY_1_9 = !!(RUBY_VERSION =~ /^1\.9/)
30
+ KNOWN_TEMPLATE_EXTENSIONS = /.*\.(erb|haml|rhtml)$/
36
31
 
37
32
  #Pass in path to the root of the Rails application
38
33
  def initialize options, processor = nil
@@ -71,15 +66,15 @@ class Brakeman::Scanner
71
66
  process_initializers
72
67
  Brakeman.notify "Processing libs..."
73
68
  process_libs
74
- Brakeman.notify "Processing routes... "
69
+ Brakeman.notify "Processing routes... "
75
70
  process_routes
76
- Brakeman.notify "Processing templates... "
71
+ Brakeman.notify "Processing templates... "
77
72
  process_templates
78
- Brakeman.notify "Processing models... "
73
+ Brakeman.notify "Processing models... "
79
74
  process_models
80
- Brakeman.notify "Processing controllers... "
75
+ Brakeman.notify "Processing controllers... "
81
76
  process_controllers
82
- Brakeman.notify "Indexing call sites... "
77
+ Brakeman.notify "Indexing call sites... "
83
78
  index_call_sites
84
79
  tracker
85
80
  end
@@ -215,7 +210,7 @@ class Brakeman::Scanner
215
210
  controller_files = Dir.glob(@app_path + "/controllers/**/*.rb").sort
216
211
  controller_files.reject! { |f| @skip_files.match f } if @skip_files
217
212
 
218
- total = controller_files.length * 2
213
+ total = controller_files.length
219
214
  current = 0
220
215
 
221
216
  controller_files.each do |f|
@@ -240,7 +235,7 @@ class Brakeman::Scanner
240
235
  current += 1
241
236
  end
242
237
 
243
- @processor.process_controller_alias controller[:src]
238
+ @processor.process_controller_alias name, controller[:src]
244
239
  end
245
240
 
246
241
  #No longer need these processed filter methods
@@ -298,7 +293,7 @@ class Brakeman::Scanner
298
293
  end
299
294
 
300
295
  def process_template path
301
- type = path.match(/.*\.(erb|haml|rhtml)$/)[1].to_sym
296
+ type = path.match(KNOWN_TEMPLATE_EXTENSIONS)[1].to_sym
302
297
  type = :erb if type == :rhtml
303
298
  name = template_path_to_name path
304
299
  text = File.read path
@@ -308,9 +303,9 @@ class Brakeman::Scanner
308
303
  if tracker.config[:escape_html]
309
304
  type = :erubis
310
305
  if options[:rails3]
311
- src = Brakeman::Rails3XSSErubis.new(text).src
306
+ src = Brakeman::Rails3Erubis.new(text).src
312
307
  else
313
- src = Brakeman::Rails2XSSErubis.new(text).src
308
+ src = Brakeman::Rails2XSSPluginErubis.new(text).src
314
309
  end
315
310
  elsif tracker.config[:erubis]
316
311
  type = :erubis
@@ -353,7 +348,7 @@ class Brakeman::Scanner
353
348
  #
354
349
  #Adds the processed models to tracker.models
355
350
  def process_models
356
- model_files = Dir.glob(@app_path + "/models/*.rb").sort
351
+ model_files = Dir.glob(@app_path + "/models/**/*.rb").sort
357
352
  model_files.reject! { |f| @skip_files.match f } if @skip_files
358
353
 
359
354
  total = model_files.length
@@ -389,111 +384,3 @@ class Brakeman::Scanner
389
384
  @ruby_parser.new.parse input
390
385
  end
391
386
  end
392
-
393
- #This is from Rails 3 version of the Erubis handler
394
- class Brakeman::Rails3XSSErubis < ::Erubis::Eruby
395
-
396
- def add_preamble(src)
397
- # src << "_buf = ActionView::SafeBuffer.new;\n"
398
- end
399
-
400
- #This is different from Rails 3 - fixes some line number issues
401
- def add_text(src, text)
402
- if text == "\n"
403
- src << "\n"
404
- elsif text.include? "\n"
405
- lines = text.split("\n")
406
- if text.match(/\n\z/)
407
- lines.each do |line|
408
- src << "@output_buffer << ('" << escape_text(line) << "'.html_safe!);\n"
409
- end
410
- else
411
- lines[0..-2].each do |line|
412
- src << "@output_buffer << ('" << escape_text(line) << "'.html_safe!);\n"
413
- end
414
-
415
- src << "@output_buffer << ('" << escape_text(lines.last) << "'.html_safe!);"
416
- end
417
- else
418
- src << "@output_buffer << ('" << escape_text(text) << "'.html_safe!);"
419
- end
420
- end
421
-
422
- BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
423
-
424
- def add_expr_literal(src, code)
425
- if code =~ BLOCK_EXPR
426
- src << '@output_buffer.append= ' << code
427
- else
428
- src << '@output_buffer.append= (' << code << ');'
429
- end
430
- end
431
-
432
- def add_stmt(src, code)
433
- if code =~ BLOCK_EXPR
434
- src << '@output_buffer.append_if_string= ' << code
435
- else
436
- super
437
- end
438
- end
439
-
440
- def add_expr_escaped(src, code)
441
- if code =~ BLOCK_EXPR
442
- src << "@output_buffer.safe_append= " << code
443
- else
444
- src << "@output_buffer.safe_concat(" << code << ");"
445
- end
446
- end
447
-
448
- #Add code to output buffer.
449
- def add_postamble(src)
450
- # src << '_buf.to_s'
451
- end
452
- end
453
-
454
- #This is from the rails_xss plugin for Rails 2
455
- class Brakeman::Rails2XSSErubis < ::Erubis::Eruby
456
- def add_preamble(src)
457
- #src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
458
- end
459
-
460
- #This is different from rails_xss - fixes some line number issues
461
- def add_text(src, text)
462
- if text == "\n"
463
- src << "\n"
464
- elsif text.include? "\n"
465
- lines = text.split("\n")
466
- if text.match(/\n\z/)
467
- lines.each do |line|
468
- src << "@output_buffer.safe_concat('" << escape_text(line) << "');\n"
469
- end
470
- else
471
- lines[0..-2].each do |line|
472
- src << "@output_buffer.safe_concat('" << escape_text(line) << "');\n"
473
- end
474
-
475
- src << "@output_buffer.safe_concat('" << escape_text(lines.last) << "');"
476
- end
477
- else
478
- src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
479
- end
480
- end
481
-
482
- BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
483
-
484
- def add_expr_literal(src, code)
485
- if code =~ BLOCK_EXPR
486
- src << "@output_buffer.safe_concat((" << $1 << ").to_s);"
487
- else
488
- src << '@output_buffer << ((' << code << ').to_s);'
489
- end
490
- end
491
-
492
- def add_expr_escaped(src, code)
493
- src << '@output_buffer << ' << escaped_expr(code) << ';'
494
- end
495
-
496
- def add_postamble(src)
497
- #src << '@output_buffer.to_s'
498
- end
499
- end
@@ -80,6 +80,23 @@ module Brakeman::Util
80
80
  hash
81
81
  end
82
82
 
83
+ #Get value from hash using key.
84
+ #
85
+ #If _key_ is a Symbol, it will be converted to a Sexp(:lit, key).
86
+ def hash_access hash, key
87
+ if key.is_a? Symbol
88
+ key = Sexp.new(:lit, key)
89
+ end
90
+
91
+ hash_iterate hash do |k, v|
92
+ if k == key
93
+ return v
94
+ end
95
+ end
96
+
97
+ nil
98
+ end
99
+
83
100
  #Adds params, session, and cookies to environment
84
101
  #so they can be replaced by their respective Sexps.
85
102
  def set_env_defaults
@@ -187,6 +204,13 @@ module Brakeman::Util
187
204
  call? exp and (exp == REQUEST_ENV or exp[1] == REQUEST_ENV)
188
205
  end
189
206
 
207
+ #Check if exp is params, cookies, or request_env
208
+ def request_value? exp
209
+ params? exp or
210
+ cookies? exp or
211
+ request_env? exp
212
+ end
213
+
190
214
  #Check if _exp_ is a Sexp.
191
215
  def sexp? exp
192
216
  exp.is_a? Sexp
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "1.5.2"
2
+ Version = "1.5.3"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 5
9
- - 2
10
- version: 1.5.2
9
+ - 3
10
+ version: 1.5.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Justin Collins
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-03-22 00:00:00 Z
18
+ date: 2012-04-10 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activesupport
@@ -133,6 +133,7 @@ files:
133
133
  - WARNING_TYPES
134
134
  - FEATURES
135
135
  - README.md
136
+ - lib/brakeman/brakeman.rake
136
137
  - lib/ruby_parser/ruby18_parser.rb
137
138
  - lib/ruby_parser/ruby_parser_extras.rb
138
139
  - lib/ruby_parser/bm_sexp.rb
@@ -193,12 +194,16 @@ files:
193
194
  - lib/brakeman/checks/check_file_access.rb
194
195
  - lib/brakeman/checks/check_response_splitting.rb
195
196
  - lib/brakeman/checks/check_basic_auth.rb
197
+ - lib/brakeman/checks/check_send.rb
196
198
  - lib/brakeman/checks/check_redirect.rb
197
199
  - lib/brakeman/checks/check_forgery_setting.rb
198
200
  - lib/brakeman/checks/check_render.rb
199
201
  - lib/brakeman/tracker.rb
200
202
  - lib/brakeman/util.rb
201
203
  - lib/brakeman/report.rb
204
+ - lib/brakeman/parsers/rails3_erubis.rb
205
+ - lib/brakeman/parsers/rails2_xss_plugin_erubis.rb
206
+ - lib/brakeman/parsers/rails2_erubis.rb
202
207
  - lib/brakeman/version.rb
203
208
  - lib/brakeman/call_index.rb
204
209
  - lib/brakeman/options.rb