brakeman 1.2.0 → 1.2.1

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/README.md CHANGED
@@ -6,9 +6,15 @@ It targets Rails versions 2.x and 3.x.
6
6
 
7
7
  There is also a [plugin available](http://brakemanscanner.org/docs/jenkins/) for Jenkins/Hudson.
8
8
 
9
- # Homepage
9
+ For even more continuous testing, try the [Guard plugin](https://github.com/oreoshake/guard-brakeman).
10
10
 
11
- http://brakemanscanner.org/
11
+ # Homepage/News
12
+
13
+ Website: http://brakemanscanner.org/
14
+
15
+ Twitter: http://twitter.com/brakemanscanner
16
+
17
+ Mailing list: brakeman@librelist.com
12
18
 
13
19
  # Installation
14
20
 
@@ -8,6 +8,9 @@ module Brakeman
8
8
  #option is set
9
9
  Warnings_Found_Exit_Code = 3
10
10
 
11
+ @debug = false
12
+ @quiet = false
13
+
11
14
  #Run Brakeman scan. Returns Tracker object.
12
15
  #
13
16
  #Options:
@@ -42,14 +45,15 @@ module Brakeman
42
45
  def self.run options
43
46
  options = set_options options
44
47
 
45
- if options[:quiet]
46
- options[:report_progress] = false
47
- $VERBOSE = nil
48
- end
48
+ @quiet = !!options[:quiet]
49
+ @debug = !!options[:debug]
50
+
51
+ options[:report_progress] = !@quiet
49
52
 
50
53
  scan options
51
54
  end
52
55
 
56
+ #Sets up options for run, checks given application path
53
57
  def self.set_options options
54
58
  if options.is_a? String
55
59
  options = { :app_path => options }
@@ -67,12 +71,13 @@ module Brakeman
67
71
 
68
72
  if File.exist? app_path + "/script/rails"
69
73
  options[:rails3] = true
70
- warn "[Notice] Detected Rails 3 application"
74
+ notify "[Notice] Detected Rails 3 application"
71
75
  end
72
76
 
73
77
  options
74
78
  end
75
79
 
80
+ #Load options from YAML file
76
81
  def self.load_options config_file
77
82
  config_file ||= ""
78
83
 
@@ -84,7 +89,7 @@ module Brakeman
84
89
  "#{File.expand_path(File.dirname(__FILE__))}/../lib/config.yaml"].each do |f|
85
90
 
86
91
  if File.exist? f and not File.directory? f
87
- warn "[Notice] Using configuration in #{f}" unless options[:quiet]
92
+ notify "[Notice] Using configuration in #{f}"
88
93
  options = YAML.load_file f
89
94
  options.each do |k,v|
90
95
  if v.is_a? Array
@@ -99,6 +104,7 @@ module Brakeman
99
104
  return {}
100
105
  end
101
106
 
107
+ #Default set of options
102
108
  def self.get_defaults
103
109
  { :skip_checks => Set.new,
104
110
  :check_arguments => true,
@@ -116,6 +122,8 @@ module Brakeman
116
122
  }
117
123
  end
118
124
 
125
+ #Determine output format based on options[:output_format]
126
+ #or options[:output_file]
119
127
  def self.get_output_format options
120
128
  #Set output format
121
129
  if options[:output_format]
@@ -147,6 +155,7 @@ module Brakeman
147
155
  end
148
156
  end
149
157
 
158
+ #Output list of checks (for `-k` option)
150
159
  def self.list_checks
151
160
  require 'brakeman/scanner'
152
161
  $stderr.puts "Available Checks:"
@@ -154,6 +163,9 @@ module Brakeman
154
163
  $stderr.puts Checks.checks.map { |c| c.to_s.match(/^Brakeman::(.*)$/)[1] }.sort.join "\n"
155
164
  end
156
165
 
166
+ #Installs Rake task for running Brakeman,
167
+ #which basically means copying `lib/brakeman/brakeman.rake` to
168
+ #`lib/tasks/brakeman.rake` in the current Rails application.
157
169
  def self.install_rake_task
158
170
  if not File.exists? "Rakefile"
159
171
  abort "No Rakefile detected"
@@ -164,7 +176,7 @@ module Brakeman
164
176
  require 'fileutils'
165
177
 
166
178
  if not File.exists? "lib/tasks"
167
- warn "Creating lib/tasks"
179
+ notify "Creating lib/tasks"
168
180
  FileUtils.mkdir_p "lib/tasks"
169
181
  end
170
182
 
@@ -173,13 +185,14 @@ module Brakeman
173
185
  FileUtils.cp "#{path}/brakeman/brakeman.rake", "lib/tasks/brakeman.rake"
174
186
 
175
187
  if File.exists? "lib/tasks/brakeman.rake"
176
- warn "Task created in lib/tasks/brakeman.rake"
177
- warn "Usage: rake brakeman:run[output_file]"
188
+ notify "Task created in lib/tasks/brakeman.rake"
189
+ notify "Usage: rake brakeman:run[output_file]"
178
190
  else
179
- warn "Could not create task"
191
+ notify "Could not create task"
180
192
  end
181
193
  end
182
194
 
195
+ #Output configuration to YAML
183
196
  def self.dump_config options
184
197
  if options[:create_config].is_a? String
185
198
  file = options[:create_config]
@@ -206,9 +219,10 @@ module Brakeman
206
219
  exit
207
220
  end
208
221
 
222
+ #Run a scan. Generally called from Brakeman.run instead of directly.
209
223
  def self.scan options
210
224
  #Load scanner
211
- warn "Loading scanner..."
225
+ notify "Loading scanner..."
212
226
 
213
227
  begin
214
228
  require 'brakeman/scanner'
@@ -219,27 +233,27 @@ module Brakeman
219
233
  #Start scanning
220
234
  scanner = Scanner.new options
221
235
 
222
- warn "[Notice] Using Ruby #{RUBY_VERSION}. Please make sure this matches the one used to run your Rails application."
236
+ notify "[Notice] Using Ruby #{RUBY_VERSION}. Please make sure this matches the one used to run your Rails application."
223
237
 
224
- warn "Processing application in #{options[:app_path]}"
238
+ notify "Processing application in #{options[:app_path]}"
225
239
  tracker = scanner.process
226
240
 
227
241
  if options[:parallel_checks]
228
- warn "Running checks in parallel..."
242
+ notify "Running checks in parallel..."
229
243
  else
230
- warn "Runnning checks..."
244
+ notify "Runnning checks..."
231
245
  end
232
246
  tracker.run_checks
233
247
 
234
248
  if options[:output_file]
235
- warn "Generating report..."
249
+ notify "Generating report..."
236
250
 
237
251
  File.open options[:output_file], "w" do |f|
238
252
  f.puts tracker.report.send(options[:output_format])
239
253
  end
240
- warn "Report saved in '#{options[:output_file]}'"
254
+ notify "Report saved in '#{options[:output_file]}'"
241
255
  elsif options[:print_report]
242
- warn "Generating report..."
256
+ notify "Generating report..."
243
257
 
244
258
  puts tracker.report.send(options[:output_format])
245
259
  end
@@ -256,9 +270,33 @@ module Brakeman
256
270
  tracker
257
271
  end
258
272
 
259
- def self.rescan tracker, files
273
+ #Rescan a subset of files in a Rails application.
274
+ #
275
+ #A full scan must have been run already to use this method.
276
+ #The returned Tracker object from Brakeman.run is used as a starting point
277
+ #for the rescan.
278
+ #
279
+ #Options may be given as a hash with the same values as Brakeman.run.
280
+ #Note that these options will be merged into the Tracker.
281
+ #
282
+ #This method returns a RescanReport object with information about the scan.
283
+ #However, the Tracker object will also be modified as the scan is run.
284
+ def self.rescan tracker, files, options = {}
260
285
  require 'brakeman/rescanner'
261
286
 
287
+ tracker.options.merge! options
288
+
289
+ @quiet = !!tracker.options[:quiet]
290
+ @debug = !!tracker.options[:debug]
291
+
262
292
  Rescanner.new(tracker.options, tracker.processor, files).recheck
263
293
  end
294
+
295
+ def self.notify message
296
+ $stderr.puts message unless @quiet
297
+ end
298
+
299
+ def self.debug message
300
+ $stderr.puts message if @debug
301
+ end
264
302
  end
@@ -55,7 +55,7 @@ class Brakeman::CallIndex
55
55
  elsif method
56
56
  calls = calls_by_method method
57
57
  else
58
- warn "Invalid arguments to CallCache#find_calls: #{options.inspect}"
58
+ notify "Invalid arguments to CallCache#find_calls: #{options.inspect}"
59
59
  end
60
60
 
61
61
  return [] if calls.nil?
@@ -89,7 +89,7 @@ class Brakeman::Checks
89
89
  unless tracker.options[:skip_checks].include? check_name or
90
90
  (tracker.options[:run_checks] and not tracker.options[:run_checks].include? check_name)
91
91
 
92
- warn " - #{check_name}"
92
+ Brakeman.notify " - #{check_name}"
93
93
 
94
94
  check = c.new(tracker)
95
95
  check.run_check
@@ -120,7 +120,7 @@ class Brakeman::Checks
120
120
  unless tracker.options[:skip_checks].include? check_name or
121
121
  (tracker.options[:run_checks] and not tracker.options[:run_checks].include? check_name)
122
122
 
123
- warn " - #{check_name}"
123
+ Brakeman.notify " - #{check_name}"
124
124
 
125
125
  threads << Thread.new do
126
126
  begin
@@ -128,7 +128,7 @@ class Brakeman::Checks
128
128
  check.run_check
129
129
  check.warnings
130
130
  rescue Exception => e
131
- warn "[#{check_name}] #{e}"
131
+ Brakeman.notify "[#{check_name}] #{e}"
132
132
  []
133
133
  end
134
134
  end
@@ -141,7 +141,7 @@ class Brakeman::Checks
141
141
 
142
142
  threads.each { |t| t.join }
143
143
 
144
- warn "Checks finished, collecting results..."
144
+ Brakeman.notify "Checks finished, collecting results..."
145
145
 
146
146
  #Collect results
147
147
  threads.each do |thread|
@@ -20,7 +20,6 @@ class Brakeman::BaseCheck < SexpProcessor
20
20
  @tracker = tracker
21
21
  @string_interp = false
22
22
  @current_set = nil
23
- @debug_mode = tracker.options[:debug]
24
23
  @current_template = @current_module = @current_class = @current_method = nil
25
24
  self.strict = false
26
25
  self.auto_shift_type = false
@@ -397,8 +396,4 @@ class Brakeman::BaseCheck < SexpProcessor
397
396
  "config/environment.rb"
398
397
  end
399
398
  end
400
-
401
- def debug_info msg
402
- Kernel.warn msg if @debug_mode
403
- end
404
399
  end
@@ -44,9 +44,11 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
44
44
  @models = tracker.models.keys
45
45
  @inspect_arguments = tracker.options[:check_arguments]
46
46
 
47
- link_to_check = Brakeman::CheckLinkTo.new(tracker)
48
- link_to_check.run_check
49
- warnings.concat link_to_check.warnings unless link_to_check.warnings.empty?
47
+ if version_between?("2.0.0", "2.9.9") and not tracker.config[:escape_html]
48
+ link_to_check = Brakeman::CheckLinkTo.new(tracker)
49
+ link_to_check.run_check
50
+ warnings.concat link_to_check.warnings unless link_to_check.warnings.empty?
51
+ end
50
52
 
51
53
  @known_dangerous = Set.new([:truncate, :concat])
52
54
 
@@ -59,10 +61,10 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
59
61
  tracker.each_template do |name, template|
60
62
  @current_template = template
61
63
  template[:outputs].each do |out|
62
- debug_info "Checking #{name} for direct XSS"
64
+ Brakeman.debug "Checking #{name} for direct XSS"
63
65
 
64
66
  unless check_for_immediate_xss out
65
- debug_info "Checking #{name} for indirect XSS"
67
+ Brakeman.debug "Checking #{name} for indirect XSS"
66
68
 
67
69
  @matched = false
68
70
  @mark = false
@@ -266,7 +268,14 @@ end
266
268
  #This _only_ checks calls to link_to
267
269
  class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
268
270
  def run_check
269
- @ignore_methods = []
271
+ @ignore_methods = Set.new([:button_to, :check_box, :escapeHTML, :escape_once,
272
+ :field_field, :fields_for, :h, :hidden_field,
273
+ :hidden_field, :hidden_field_tag, :image_tag, :label,
274
+ :mail_to, :radio_button, :select,
275
+ :submit_tag, :text_area, :text_field,
276
+ :text_field_tag, :url_encode, :url_for,
277
+ :will_paginate] ).merge tracker.options[:safe_methods]
278
+
270
279
  @known_dangerous = []
271
280
  #Ideally, I think this should also check to see if people are setting
272
281
  #:escape => false
@@ -15,7 +15,7 @@ class Brakeman::CheckDefaultRoutes < Brakeman::BaseCheck
15
15
  :confidence => CONFIDENCE[:high],
16
16
  :file => "#{tracker.options[:app_path]}/config/routes.rb"
17
17
  else #Report each controller separately
18
- debug_info "Checking each controller for default routes"
18
+ Brakeman.debug "Checking each controller for default routes"
19
19
 
20
20
  tracker.routes.each do |name, actions|
21
21
  if actions.is_a? Array and actions[0] == :allow_all_actions
@@ -7,10 +7,10 @@ class Brakeman::CheckEvaluation < Brakeman::BaseCheck
7
7
 
8
8
  #Process calls
9
9
  def run_check
10
- debug_info "Finding eval-like calls"
10
+ Brakeman.debug "Finding eval-like calls"
11
11
  calls = tracker.find_call :method => [:eval, :instance_eval, :class_eval, :module_eval]
12
12
 
13
- debug_info "Processing eval-like calls"
13
+ Brakeman.debug "Processing eval-like calls"
14
14
  calls.each do |call|
15
15
  process_result call
16
16
  end
@@ -13,13 +13,13 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
13
13
 
14
14
  #Check models, controllers, and views for command injection.
15
15
  def run_check
16
- debug_info "Finding system calls using ``"
16
+ Brakeman.debug "Finding system calls using ``"
17
17
  check_for_backticks tracker
18
18
 
19
- debug_info "Finding other system calls"
19
+ Brakeman.debug "Finding other system calls"
20
20
  calls = tracker.find_call :targets => [:IO, :Open3, :Kernel, nil], :methods => [:exec, :popen, :popen3, :syscall, :system]
21
21
 
22
- debug_info "Processing system calls"
22
+ Brakeman.debug "Processing system calls"
23
23
  calls.each do |result|
24
24
  process_result result
25
25
  end
@@ -6,16 +6,16 @@ class Brakeman::CheckFileAccess < Brakeman::BaseCheck
6
6
  Brakeman::Checks.add self
7
7
 
8
8
  def run_check
9
- debug_info "Finding possible file access"
9
+ Brakeman.debug "Finding possible file access"
10
10
  methods = tracker.find_call :targets => [:Dir, :File, :IO, :Kernel, :"Net::FTP", :"Net::HTTP", :PStore, :Pathname, :Shell, :YAML], :methods => [:[], :chdir, :chroot, :delete, :entries, :foreach, :glob, :install, :lchmod, :lchown, :link, :load, :load_file, :makedirs, :move, :new, :open, :read, :read_lines, :rename, :rmdir, :safe_unlink, :symlink, :syscopy, :sysopen, :truncate, :unlink]
11
11
 
12
- debug_info "Finding calls to load()"
12
+ Brakeman.debug "Finding calls to load()"
13
13
  methods.concat tracker.find_call :target => false, :method => :load
14
14
 
15
- debug_info "Finding calls using FileUtils"
15
+ Brakeman.debug "Finding calls using FileUtils"
16
16
  methods.concat tracker.find_call :target => :FileUtils
17
17
 
18
- debug_info "Processing found calls"
18
+ Brakeman.debug "Processing found calls"
19
19
  methods.each do |call|
20
20
  process_result call
21
21
  end
@@ -28,7 +28,7 @@ class Brakeman::CheckMailTo < Brakeman::BaseCheck
28
28
  #Check for javascript encoding of mail_to address
29
29
  # mail_to email, name, :encode => :javascript
30
30
  def mail_to_javascript?
31
- debug_info "Checking calls to mail_to for javascript encoding"
31
+ Brakeman.debug "Checking calls to mail_to for javascript encoding"
32
32
 
33
33
  tracker.find_call(:target => false, :method => :mail_to).each do |result|
34
34
  call = result[:call]
@@ -21,7 +21,7 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
21
21
 
22
22
  @results = Set.new
23
23
 
24
- debug_info "Finding possible mass assignment calls on #{models.length} models"
24
+ Brakeman.debug "Finding possible mass assignment calls on #{models.length} models"
25
25
  calls = tracker.find_call :chained => true, :targets => models, :methods => [:new,
26
26
  :attributes=,
27
27
  :update_attribute,
@@ -30,7 +30,7 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
30
30
  :create,
31
31
  :create!]
32
32
 
33
- debug_info "Processing possible mass assignment calls"
33
+ Brakeman.debug "Processing possible mass assignment calls"
34
34
  calls.each do |result|
35
35
  process_result result
36
36
  end
@@ -29,7 +29,7 @@ class Brakeman::CheckQuoteTableName < Brakeman::BaseCheck
29
29
  end
30
30
 
31
31
  def uses_quote_table_name?
32
- debug_info "Finding calls to quote_table_name()"
32
+ Brakeman.debug "Finding calls to quote_table_name()"
33
33
 
34
34
  not tracker.find_call(:target => false, :method => :quote_table_name).empty?
35
35
  end
@@ -9,7 +9,7 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
9
9
  Brakeman::Checks.add self
10
10
 
11
11
  def run_check
12
- debug_info "Finding calls to redirect_to()"
12
+ Brakeman.debug "Finding calls to redirect_to()"
13
13
 
14
14
  @tracker.find_call(:target => false, :method => :redirect_to).each do |res|
15
15
  process_result res
@@ -42,7 +42,7 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
42
42
  #which can be used to enable/disable reporting output of method calls which use
43
43
  #user input as arguments.
44
44
  def include_user_input? call
45
- debug_info "Checking if call includes user input"
45
+ Brakeman.debug "Checking if call includes user input"
46
46
 
47
47
  if tracker.options[:ignore_redirect_to_model] and call? call[3][1] and
48
48
  call[3][1][2] == :new and call[3][1][1]
@@ -6,7 +6,7 @@ class Brakeman::CheckSendFile < Brakeman::CheckFileAccess
6
6
  Brakeman::Checks.add self
7
7
 
8
8
  def run_check
9
- debug_info "Finding all calls to send_file()"
9
+ Brakeman.debug "Finding all calls to send_file()"
10
10
 
11
11
  methods = tracker.find_call :target => false, :method => :send_file
12
12
 
@@ -14,7 +14,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
14
14
  def run_check
15
15
  @rails_version = tracker.config[:rails_version]
16
16
 
17
- debug_info "Finding possible SQL calls on models"
17
+ Brakeman.debug "Finding possible SQL calls on models"
18
18
  if tracker.options[:rails3]
19
19
  calls = tracker.find_call :targets => tracker.models.keys,
20
20
  :methods => /^(find.*|first|last|all|where|order|group|having)$/,
@@ -25,16 +25,16 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
25
25
  :chained => true
26
26
  end
27
27
 
28
- debug_info "Finding possible SQL calls with no target"
28
+ Brakeman.debug "Finding possible SQL calls with no target"
29
29
  calls.concat tracker.find_call(:target => nil, :method => /^(find.*|last|first|all|count|sum|average|minumum|maximum|count_by_sql)$/)
30
30
 
31
- debug_info "Finding possible SQL calls using constantized()"
31
+ Brakeman.debug "Finding possible SQL calls using constantized()"
32
32
  calls.concat tracker.find_call(:method => /^(find.*|last|first|all|count|sum|average|minumum|maximum|count_by_sql)$/).select { |result| constantize_call? result }
33
33
 
34
- debug_info "Finding calls to named_scope or scope"
34
+ Brakeman.debug "Finding calls to named_scope or scope"
35
35
  calls.concat find_scope_calls
36
36
 
37
- debug_info "Processing possible SQL calls"
37
+ Brakeman.debug "Processing possible SQL calls"
38
38
  calls.each do |c|
39
39
  process_result c
40
40
  end
@@ -23,7 +23,7 @@ class Brakeman::CheckStripTags < Brakeman::BaseCheck
23
23
  end
24
24
 
25
25
  def uses_strip_tags?
26
- debug_info "Finding calls to strip_tags()"
26
+ Brakeman.debug "Finding calls to strip_tags()"
27
27
 
28
28
  not tracker.find_call(:target => false, :method => :strip_tags).empty?
29
29
  end
@@ -6,7 +6,7 @@ class Brakeman::CheckTranslateBug < Brakeman::BaseCheck
6
6
  Brakeman::Checks.add self
7
7
 
8
8
  def run_check
9
- if (version_between?('2.3.0', '2.3.99') and tracker.options[:escape_html]) or
9
+ if (version_between?('2.3.0', '2.3.99') and tracker.config[:escape_html]) or
10
10
  version_between?('3.0.0', '3.0.10') or
11
11
  version_between?('3.1.0', '3.1.1')
12
12
 
@@ -34,7 +34,7 @@ class Brakeman::CheckTranslateBug < Brakeman::BaseCheck
34
34
  end
35
35
 
36
36
  def uses_translate?
37
- debug_info "Finding calls to translate() or t()"
37
+ Brakeman.debug "Finding calls to translate() or t()"
38
38
 
39
39
  not tracker.find_call(:target => nil, :methods => [:t, :translate]).empty?
40
40
  end
@@ -23,7 +23,7 @@ class Brakeman::CheckWithoutProtection < Brakeman::BaseCheck
23
23
 
24
24
  @results = Set.new
25
25
 
26
- debug_info "Finding all mass assignments"
26
+ Brakeman.debug "Finding all mass assignments"
27
27
  calls = tracker.find_call :targets => models, :methods => [:new,
28
28
  :attributes=,
29
29
  :update_attribute,
@@ -32,7 +32,7 @@ class Brakeman::CheckWithoutProtection < Brakeman::BaseCheck
32
32
  :create,
33
33
  :create!]
34
34
 
35
- debug_info "Processing all mass assignments"
35
+ Brakeman.debug "Processing all mass assignments"
36
36
  calls.each do |result|
37
37
  process_result result
38
38
  end
@@ -87,7 +87,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
87
87
  method = find_method name, @current_class
88
88
 
89
89
  if method.nil?
90
- warn "[Notice] Could not find filter #{name}" if @tracker.options[:debug]
90
+ Brakeman.debug "[Notice] Could not find filter #{name}"
91
91
  return
92
92
  end
93
93
 
@@ -207,7 +207,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
207
207
  when :lit, :str
208
208
  filter[option] = value[1]
209
209
  else
210
- warn "[Notice] Unknown before_filter value: #{option} => #{value}" if @tracker.options[:debug]
210
+ Brakeman.debug "[Notice] Unknown before_filter value: #{option} => #{value}"
211
211
  end
212
212
  else
213
213
  filter[:all] = true
@@ -22,7 +22,7 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
22
22
  #s(:class, NAME, PARENT, s(:scope ...))
23
23
  def process_class exp
24
24
  if @controller
25
- warn "[Notice] Skipping inner class: #{class_name exp[1]}" if @tracker.options[:debug]
25
+ Brakeman.debug "[Notice] Skipping inner class: #{class_name exp[1]}"
26
26
  return ignore
27
27
  end
28
28
 
@@ -83,7 +83,7 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
83
83
  unless Dir.glob("#{@tracker.options[:app_path]}/app/views/layouts/#{name}.html.{erb,haml}").empty?
84
84
  @controller[:layout] = "layouts/#{name}"
85
85
  else
86
- warn "[Notice] Layout not found: #{name}" if @tracker.options[:debug]
86
+ Brakeman.debug "[Notice] Layout not found: #{name}"
87
87
  end
88
88
  elsif sexp? args[-1] and (args[-1][0] == :nil or args[-1][0] == :false)
89
89
  #layout :false or layout nil
@@ -37,7 +37,7 @@ class Brakeman::Rails2ConfigProcessor < Brakeman::BaseProcessor
37
37
  target = process target if sexp? target
38
38
 
39
39
  if exp[2] == :gem and exp[3][1][1] == "erubis"
40
- warn "[Notice] Using Erubis for ERB templates"
40
+ Brakeman.notify "[Notice] Using Erubis for ERB templates"
41
41
  @tracker.config[:erubis] = true
42
42
  end
43
43
 
@@ -21,10 +21,13 @@ module Brakeman::RenderHelper
21
21
 
22
22
  #Processes layout
23
23
  def process_layout name = nil
24
- layout = name || layout_name
25
- return unless layout
24
+ if name.nil? and defined? layout_name
25
+ name = layout_name
26
+ end
27
+
28
+ return unless name
26
29
 
27
- process_template layout, nil
30
+ process_template name, nil
28
31
  end
29
32
 
30
33
  #Determines file name for partial and then processes it
@@ -50,7 +53,7 @@ module Brakeman::RenderHelper
50
53
  name = name.to_s.gsub(/^\//, "")
51
54
  template = @tracker.templates[name.to_sym]
52
55
  unless template
53
- warn "[Notice] No such template: #{name}" if @tracker.options[:debug]
56
+ Brakeman.debug "[Notice] No such template: #{name}"
54
57
  return
55
58
  end
56
59
 
@@ -19,7 +19,7 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
19
19
  #s(:class, NAME, PARENT, s(:scope ...))
20
20
  def process_class exp
21
21
  if @model
22
- warn "[Notice] Skipping inner class: #{class_name exp[1]}" if @tracker.options[:debug]
22
+ Brakeman.debug "[Notice] Skipping inner class: #{class_name exp[1]}"
23
23
  ignore
24
24
  else
25
25
  @model = { :name => class_name(exp[1]),
@@ -56,6 +56,8 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
56
56
  case method
57
57
  when :private, :protected, :public
58
58
  @visibility = method
59
+ when :attr_accessible
60
+ @model[:attr_accessible] ||= []
59
61
  else
60
62
  #??
61
63
  end
@@ -19,7 +19,7 @@ class Brakeman::OutputProcessor < Ruby2Ruby
19
19
  begin
20
20
  super exp if sexp? exp and not exp.empty?
21
21
  rescue Exception => e
22
- warn "While formatting #{exp}: #{e}\n#{e.backtrace.join("\n")}" if @tracker.options[:debug]
22
+ Brakeman.debug "While formatting #{exp}: #{e}\n#{e.backtrace.join("\n")}"
23
23
  end
24
24
  end
25
25
 
@@ -83,7 +83,7 @@ class Brakeman::Report
83
83
 
84
84
 
85
85
  tracker.errors.each do |w|
86
- p w if tracker.options[:debug]
86
+ Brakeman.debug w.inspect
87
87
 
88
88
  if html
89
89
  w[:error] = CGI.escapeHTML w[:error]
@@ -45,7 +45,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
45
45
 
46
46
  SCAN_ORDER.each do |type|
47
47
  paths_by_type[type].each do |path|
48
- warn "Rescanning #{path} as #{type}" if tracker.options[:debug]
48
+ Brakeman.debug "Rescanning #{path} as #{type}"
49
49
 
50
50
  if rescan_file path, type
51
51
  @changes = true
@@ -244,4 +244,12 @@ class Brakeman::RescanReport
244
244
  def diff
245
245
  @diff ||= @new_results.diff(@old_results)
246
246
  end
247
+
248
+ def to_s
249
+ <<-OUTPUT
250
+ Total warnings: #{all_warnings.length}
251
+ Fixed warnings: #{fixed_warnings.length}
252
+ New warnings: #{new_warnings.length}
253
+ OUTPUT
254
+ end
247
255
  end
@@ -51,23 +51,23 @@ class Brakeman::Scanner
51
51
 
52
52
  #Process everything in the Rails application
53
53
  def process
54
- warn "Processing configuration..."
54
+ Brakeman.notify "Processing configuration..."
55
55
  process_config
56
- warn "Processing gems..."
56
+ Brakeman.notify "Processing gems..."
57
57
  process_gems
58
- warn "Processing initializers..."
58
+ Brakeman.notify "Processing initializers..."
59
59
  process_initializers
60
- warn "Processing libs..."
60
+ Brakeman.notify "Processing libs..."
61
61
  process_libs
62
- warn "Processing routes... "
62
+ Brakeman.notify "Processing routes... "
63
63
  process_routes
64
- warn "Processing templates... "
64
+ Brakeman.notify "Processing templates... "
65
65
  process_templates
66
- warn "Processing models... "
66
+ Brakeman.notify "Processing models... "
67
67
  process_models
68
- warn "Processing controllers... "
68
+ Brakeman.notify "Processing controllers... "
69
69
  process_controllers
70
- warn "Indexing call sites... "
70
+ Brakeman.notify "Indexing call sites... "
71
71
  index_call_sites
72
72
  tracker
73
73
  end
@@ -89,7 +89,7 @@ class Brakeman::Scanner
89
89
  (File.exists? "#@path/Gemfile" and File.read("#@path/Gemfile").include? "rails_xss")
90
90
 
91
91
  tracker.config[:escape_html] = true
92
- warn "[Notice] Escaping HTML by default"
92
+ Brakeman.notify "[Notice] Escaping HTML by default"
93
93
  end
94
94
  end
95
95
 
@@ -99,7 +99,7 @@ class Brakeman::Scanner
99
99
  end
100
100
 
101
101
  rescue Exception => e
102
- warn "[Notice] Error while processing config/#{file}"
102
+ Brakeman.notify "[Notice] Error while processing config/#{file}"
103
103
  tracker.error e.exception(e.message + "\nwhile processing Gemfile"), e.backtrace
104
104
  end
105
105
 
@@ -115,7 +115,7 @@ class Brakeman::Scanner
115
115
  end
116
116
  end
117
117
  rescue Exception => e
118
- warn "[Notice] Error while processing Gemfile."
118
+ Brakeman.notify "[Notice] Error while processing Gemfile."
119
119
  tracker.error e.exception(e.message + "\nWhile processing Gemfile"), e.backtrace
120
120
  end
121
121
 
@@ -144,7 +144,7 @@ class Brakeman::Scanner
144
144
  #Adds parsed information to tracker.libs.
145
145
  def process_libs
146
146
  if options[:skip_libs]
147
- warn '[Skipping]'
147
+ Brakeman.notify '[Skipping]'
148
148
  return
149
149
  end
150
150
 
@@ -153,7 +153,7 @@ class Brakeman::Scanner
153
153
  current = 0
154
154
 
155
155
  lib_files.each do |f|
156
- warn "Processing #{f}" if options[:debug]
156
+ Brakeman.debug "Processing #{f}"
157
157
  if @report_progress
158
158
  $stderr.print " #{current}/#{total} files processed\r"
159
159
  current += 1
@@ -183,11 +183,11 @@ class Brakeman::Scanner
183
183
  @processor.process_routes parse_ruby(File.read("#@path/config/routes.rb"))
184
184
  rescue Exception => e
185
185
  tracker.error e.exception(e.message + "\nWhile processing routes.rb"), e.backtrace
186
- warn "[Notice] Error while processing routes - assuming all public controller methods are actions."
186
+ Brakeman.notify "[Notice] Error while processing routes - assuming all public controller methods are actions."
187
187
  options[:assume_all_routes] = true
188
188
  end
189
189
  else
190
- warn "[Notice] No route information found"
190
+ Brakeman.notify "[Notice] No route information found"
191
191
  end
192
192
  end
193
193
 
@@ -200,7 +200,7 @@ class Brakeman::Scanner
200
200
  current = 0
201
201
 
202
202
  controller_files.each do |f|
203
- warn "Processing #{f}" if options[:debug]
203
+ Brakeman.debug "Processing #{f}"
204
204
  if @report_progress
205
205
  $stderr.print " #{current}/#{total} files processed\r"
206
206
  current += 1
@@ -212,7 +212,7 @@ class Brakeman::Scanner
212
212
  current = 0
213
213
  total = tracker.controllers.length
214
214
 
215
- warn "Processing data flow in controllers..."
215
+ Brakeman.notify "Processing data flow in controllers..."
216
216
 
217
217
  tracker.controllers.each do |name, controller|
218
218
  if @report_progress
@@ -258,7 +258,7 @@ class Brakeman::Scanner
258
258
  total = tracker.templates.length
259
259
  count = 0
260
260
 
261
- warn "Processing data flow in templates..."
261
+ Brakeman.notify "Processing data flow in templates..."
262
262
 
263
263
  tracker.templates.keys.dup.each do |name|
264
264
  if @report_progress
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "1.2.0"
2
+ Version = "1.2.1"
3
3
  end
@@ -5,6 +5,8 @@ class Brakeman::Warning
5
5
 
6
6
  attr_accessor :code, :context, :file, :message
7
7
 
8
+ TEXT_CONFIDENCE = [ "High", "Medium", "Weak" ]
9
+
8
10
  #+options[:result]+ can be a result from Tracker#find_call. Otherwise, it can be +nil+.
9
11
  def initialize options = {}
10
12
  @view_name = nil
@@ -111,4 +113,13 @@ class Brakeman::Warning
111
113
 
112
114
  @row
113
115
  end
116
+
117
+ def to_s
118
+ output = "(#{TEXT_CONFIDENCE[self.confidence]}) #{self.warning_type} - #{self.message}"
119
+ output << " near line #{self.line}" if self.line
120
+ output << " in #{self.file}" if self.file
121
+ output << ": #{self.format_code}" if self.code
122
+
123
+ output
124
+ end
114
125
  end
metadata CHANGED
@@ -1,127 +1,101 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: brakeman
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 2
8
- - 0
9
- version: 1.2.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.1
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Justin Collins
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2012-01-13 00:00:00 -08:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-01-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: activesupport
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &76221240 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
31
22
  type: :runtime
32
- version_requirements: *id001
33
- - !ruby/object:Gem::Dependency
34
- name: i18n
35
23
  prerelease: false
36
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *76221240
25
+ - !ruby/object:Gem::Dependency
26
+ name: i18n
27
+ requirement: &76220920 !ruby/object:Gem::Requirement
37
28
  none: false
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
44
33
  type: :runtime
45
- version_requirements: *id002
46
- - !ruby/object:Gem::Dependency
47
- name: ruby2ruby
48
34
  prerelease: false
49
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *76220920
36
+ - !ruby/object:Gem::Dependency
37
+ name: ruby2ruby
38
+ requirement: &76220320 !ruby/object:Gem::Requirement
50
39
  none: false
51
- requirements:
40
+ requirements:
52
41
  - - ~>
53
- - !ruby/object:Gem::Version
54
- segments:
55
- - 1
56
- - 2
57
- version: "1.2"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.2'
58
44
  type: :runtime
59
- version_requirements: *id003
60
- - !ruby/object:Gem::Dependency
61
- name: ruport
62
45
  prerelease: false
63
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *76220320
47
+ - !ruby/object:Gem::Dependency
48
+ name: ruport
49
+ requirement: &76219720 !ruby/object:Gem::Requirement
64
50
  none: false
65
- requirements:
51
+ requirements:
66
52
  - - ~>
67
- - !ruby/object:Gem::Version
68
- segments:
69
- - 1
70
- - 6
71
- version: "1.6"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
72
55
  type: :runtime
73
- version_requirements: *id004
74
- - !ruby/object:Gem::Dependency
75
- name: erubis
76
56
  prerelease: false
77
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *76219720
58
+ - !ruby/object:Gem::Dependency
59
+ name: erubis
60
+ requirement: &76943790 !ruby/object:Gem::Requirement
78
61
  none: false
79
- requirements:
62
+ requirements:
80
63
  - - ~>
81
- - !ruby/object:Gem::Version
82
- segments:
83
- - 2
84
- - 6
85
- version: "2.6"
64
+ - !ruby/object:Gem::Version
65
+ version: '2.6'
86
66
  type: :runtime
87
- version_requirements: *id005
88
- - !ruby/object:Gem::Dependency
89
- name: haml
90
67
  prerelease: false
91
- requirement: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *76943790
69
+ - !ruby/object:Gem::Dependency
70
+ name: haml
71
+ requirement: &76943560 !ruby/object:Gem::Requirement
92
72
  none: false
93
- requirements:
73
+ requirements:
94
74
  - - ~>
95
- - !ruby/object:Gem::Version
96
- segments:
97
- - 3
98
- - 0
99
- version: "3.0"
75
+ - !ruby/object:Gem::Version
76
+ version: '3.0'
100
77
  type: :runtime
101
- version_requirements: *id006
102
- - !ruby/object:Gem::Dependency
103
- name: sass
104
78
  prerelease: false
105
- requirement: &id007 !ruby/object:Gem::Requirement
79
+ version_requirements: *76943560
80
+ - !ruby/object:Gem::Dependency
81
+ name: sass
82
+ requirement: &76943330 !ruby/object:Gem::Requirement
106
83
  none: false
107
- requirements:
84
+ requirements:
108
85
  - - ~>
109
- - !ruby/object:Gem::Version
110
- segments:
111
- - 3
112
- - 0
113
- version: "3.0"
86
+ - !ruby/object:Gem::Version
87
+ version: '3.0'
114
88
  type: :runtime
115
- version_requirements: *id007
116
- description: Brakeman detects security vulnerabilities in Ruby on Rails applications via static analysis.
89
+ prerelease: false
90
+ version_requirements: *76943330
91
+ description: Brakeman detects security vulnerabilities in Ruby on Rails applications
92
+ via static analysis.
117
93
  email:
118
- executables:
94
+ executables:
119
95
  - brakeman
120
96
  extensions: []
121
-
122
97
  extra_rdoc_files: []
123
-
124
- files:
98
+ files:
125
99
  - bin/brakeman
126
100
  - WARNING_TYPES
127
101
  - FEATURES
@@ -194,37 +168,28 @@ files:
194
168
  - lib/brakeman/processor.rb
195
169
  - lib/brakeman.rb
196
170
  - lib/brakeman/format/style.css
197
- has_rdoc: true
198
171
  homepage: http://brakemanscanner.org
199
172
  licenses: []
200
-
201
173
  post_install_message:
202
174
  rdoc_options: []
203
-
204
- require_paths:
175
+ require_paths:
205
176
  - lib
206
- required_ruby_version: !ruby/object:Gem::Requirement
177
+ required_ruby_version: !ruby/object:Gem::Requirement
207
178
  none: false
208
- requirements:
209
- - - ">="
210
- - !ruby/object:Gem::Version
211
- segments:
212
- - 0
213
- version: "0"
214
- required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ! '>='
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ required_rubygems_version: !ruby/object:Gem::Requirement
215
184
  none: false
216
- requirements:
217
- - - ">="
218
- - !ruby/object:Gem::Version
219
- segments:
220
- - 0
221
- version: "0"
185
+ requirements:
186
+ - - ! '>='
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
222
189
  requirements: []
223
-
224
190
  rubyforge_project:
225
- rubygems_version: 1.3.7
191
+ rubygems_version: 1.8.10
226
192
  signing_key:
227
193
  specification_version: 3
228
194
  summary: Security vulnerability scanner for Ruby on Rails.
229
195
  test_files: []
230
-