brakeman-lib 4.5.0 → 4.5.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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +15 -0
  3. data/README.md +6 -6
  4. data/lib/brakeman.rb +7 -0
  5. data/lib/brakeman/app_tree.rb +34 -22
  6. data/lib/brakeman/checks.rb +7 -7
  7. data/lib/brakeman/checks/base_check.rb +9 -9
  8. data/lib/brakeman/checks/check_cross_site_scripting.rb +5 -0
  9. data/lib/brakeman/checks/check_default_routes.rb +5 -0
  10. data/lib/brakeman/checks/check_deserialize.rb +52 -0
  11. data/lib/brakeman/checks/check_dynamic_finders.rb +1 -1
  12. data/lib/brakeman/checks/check_force_ssl.rb +27 -0
  13. data/lib/brakeman/checks/check_json_parsing.rb +5 -0
  14. data/lib/brakeman/checks/check_link_to_href.rb +6 -1
  15. data/lib/brakeman/checks/check_mail_to.rb +1 -1
  16. data/lib/brakeman/checks/check_model_attr_accessible.rb +1 -1
  17. data/lib/brakeman/checks/check_model_attributes.rb +12 -50
  18. data/lib/brakeman/checks/check_model_serialize.rb +1 -1
  19. data/lib/brakeman/checks/check_nested_attributes_bypass.rb +3 -3
  20. data/lib/brakeman/checks/check_secrets.rb +1 -1
  21. data/lib/brakeman/checks/check_session_settings.rb +10 -10
  22. data/lib/brakeman/checks/check_simple_format.rb +5 -0
  23. data/lib/brakeman/checks/check_skip_before_filter.rb +1 -1
  24. data/lib/brakeman/checks/check_sql.rb +15 -17
  25. data/lib/brakeman/checks/check_validation_regex.rb +1 -1
  26. data/lib/brakeman/file_parser.rb +6 -8
  27. data/lib/brakeman/file_path.rb +71 -0
  28. data/lib/brakeman/options.rb +7 -0
  29. data/lib/brakeman/parsers/template_parser.rb +3 -3
  30. data/lib/brakeman/processor.rb +3 -4
  31. data/lib/brakeman/processors/alias_processor.rb +12 -6
  32. data/lib/brakeman/processors/base_processor.rb +8 -7
  33. data/lib/brakeman/processors/controller_alias_processor.rb +10 -7
  34. data/lib/brakeman/processors/controller_processor.rb +5 -9
  35. data/lib/brakeman/processors/haml_template_processor.rb +5 -0
  36. data/lib/brakeman/processors/lib/module_helper.rb +8 -8
  37. data/lib/brakeman/processors/lib/processor_helper.rb +3 -3
  38. data/lib/brakeman/processors/lib/rails2_config_processor.rb +3 -3
  39. data/lib/brakeman/processors/lib/rails2_route_processor.rb +2 -2
  40. data/lib/brakeman/processors/lib/rails3_config_processor.rb +3 -3
  41. data/lib/brakeman/processors/lib/rails3_route_processor.rb +2 -2
  42. data/lib/brakeman/processors/lib/render_helper.rb +2 -2
  43. data/lib/brakeman/processors/lib/render_path.rb +18 -1
  44. data/lib/brakeman/processors/library_processor.rb +5 -5
  45. data/lib/brakeman/processors/model_processor.rb +4 -5
  46. data/lib/brakeman/processors/output_processor.rb +5 -0
  47. data/lib/brakeman/processors/template_alias_processor.rb +4 -5
  48. data/lib/brakeman/processors/template_processor.rb +4 -4
  49. data/lib/brakeman/report.rb +3 -3
  50. data/lib/brakeman/report/ignore/config.rb +2 -3
  51. data/lib/brakeman/report/ignore/interactive.rb +2 -2
  52. data/lib/brakeman/report/pager.rb +1 -0
  53. data/lib/brakeman/report/report_base.rb +51 -6
  54. data/lib/brakeman/report/report_codeclimate.rb +3 -3
  55. data/lib/brakeman/report/report_hash.rb +1 -1
  56. data/lib/brakeman/report/report_html.rb +2 -2
  57. data/lib/brakeman/report/report_json.rb +1 -24
  58. data/lib/brakeman/report/report_table.rb +20 -4
  59. data/lib/brakeman/report/report_tabs.rb +1 -1
  60. data/lib/brakeman/report/report_text.rb +2 -2
  61. data/lib/brakeman/rescanner.rb +9 -12
  62. data/lib/brakeman/scanner.rb +19 -14
  63. data/lib/brakeman/tracker.rb +4 -4
  64. data/lib/brakeman/tracker/collection.rb +4 -3
  65. data/lib/brakeman/tracker/config.rb +6 -0
  66. data/lib/brakeman/util.rb +1 -147
  67. data/lib/brakeman/version.rb +1 -1
  68. data/lib/brakeman/warning.rb +23 -13
  69. data/lib/brakeman/warning_codes.rb +1 -0
  70. data/lib/ruby_parser/bm_sexp_processor.rb +1 -0
  71. metadata +20 -10
@@ -12,7 +12,7 @@ class Brakeman::Tracker
12
12
  attr_accessor :controllers, :constants, :templates, :models, :errors,
13
13
  :checks, :initializers, :config, :routes, :processor, :libs,
14
14
  :template_cache, :options, :filter_cache, :start_time, :end_time,
15
- :duration, :ignored_filter
15
+ :duration, :ignored_filter, :app_tree
16
16
 
17
17
  #Place holder when there should be a model, but it is not
18
18
  #clear what model it will be.
@@ -34,7 +34,7 @@ class Brakeman::Tracker
34
34
  #we can match models later without knowing precisely what
35
35
  #class they are.
36
36
  @models = {}
37
- @models[UNKNOWN_MODEL] = Brakeman::Model.new(UNKNOWN_MODEL, nil, nil, nil, self)
37
+ @models[UNKNOWN_MODEL] = Brakeman::Model.new(UNKNOWN_MODEL, nil, @app_tree.file_path("NOT_REAL.rb"), nil, self)
38
38
  @routes = {}
39
39
  @initializers = {}
40
40
  @errors = []
@@ -71,7 +71,7 @@ class Brakeman::Tracker
71
71
  #Run a set of checks on the current information. Results will be stored
72
72
  #in Tracker#checks.
73
73
  def run_checks
74
- @checks = Brakeman::Checks.run_checks(@app_tree, self)
74
+ @checks = Brakeman::Checks.run_checks(self)
75
75
 
76
76
  @end_time = Time.now
77
77
  @duration = @end_time - @start_time
@@ -172,7 +172,7 @@ class Brakeman::Tracker
172
172
 
173
173
  #Returns a Report with this Tracker's information
174
174
  def report
175
- Brakeman::Report.new(@app_tree, self)
175
+ Brakeman::Report.new(self)
176
176
  end
177
177
 
178
178
  def warnings
@@ -9,13 +9,14 @@ module Brakeman
9
9
  def initialize name, parent, file_name, src, tracker
10
10
  @name = name
11
11
  @parent = parent
12
- @file_name = file_name
13
- @files = [ file_name ]
14
- @src = { file_name => src }
12
+ @files = []
13
+ @src = {}
15
14
  @includes = []
16
15
  @methods = { :public => {}, :private => {}, :protected => {} }
17
16
  @options = {}
18
17
  @tracker = tracker
18
+
19
+ add_file file_name, src
19
20
  end
20
21
 
21
22
  def ancestor? parent, seen={}
@@ -97,6 +97,12 @@ module Brakeman
97
97
  tracker.options[:rails4] = true
98
98
  tracker.options[:rails5] = true
99
99
  Brakeman.notify "[Notice] Detected Rails 5 application"
100
+ elsif @rails_version.start_with? "6"
101
+ tracker.options[:rails3] = true
102
+ tracker.options[:rails4] = true
103
+ tracker.options[:rails5] = true
104
+ tracker.options[:rails6] = true
105
+ Brakeman.notify "[Notice] Detected Rails 6 application"
100
106
  end
101
107
  end
102
108
  end
@@ -346,158 +346,12 @@ module Brakeman::Util
346
346
  @tracker.config.rails_version
347
347
  end
348
348
 
349
- #Return file name related to given warning. Uses +warning.file+ if it exists
350
- def file_for warning, tracker = nil
351
- if tracker.nil?
352
- tracker = @tracker || self.tracker
353
- end
354
-
355
- if warning.file
356
- File.expand_path warning.file, tracker.app_path
357
- elsif warning.template and warning.template.file
358
- warning.template.file
359
- else
360
- case warning.warning_set
361
- when :controller
362
- file_by_name warning.controller, :controller, tracker
363
- when :template
364
- file_by_name warning.template.name, :template, tracker
365
- when :model
366
- file_by_name warning.model, :model, tracker
367
- when :warning
368
- file_by_name warning.class, nil, tracker
369
- else
370
- nil
371
- end
372
- end
373
- end
374
-
375
- #Attempt to determine path to context file based on the reported name
376
- #in the warning.
377
- #
378
- #For example,
379
- #
380
- # file_by_name FileController #=> "/rails/root/app/controllers/file_controller.rb
381
- def file_by_name name, type, tracker = nil
382
- return nil unless name
383
- string_name = name.to_s
384
- name = name.to_sym
385
-
386
- unless type
387
- if string_name =~ /Controller$/
388
- type = :controller
389
- elsif camelize(string_name) == string_name # This is not always true
390
- type = :model
391
- else
392
- type = :template
393
- end
394
- end
395
-
396
- path = tracker.app_path
397
-
398
- case type
399
- when :controller
400
- if tracker.controllers[name]
401
- path = tracker.controllers[name].file
402
- else
403
- path += "/app/controllers/#{underscore(string_name)}.rb"
404
- end
405
- when :model
406
- if tracker.models[name]
407
- path = tracker.models[name].file
408
- else
409
- path += "/app/models/#{underscore(string_name)}.rb"
410
- end
411
- when :template
412
- if tracker.templates[name] and tracker.templates[name].file
413
- path = tracker.templates[name].file
414
- elsif string_name.include? " "
415
- name = string_name.split[0].to_sym
416
- path = file_for tracker, name, :template
417
- else
418
- path = nil
419
- end
420
- end
421
-
422
- path
423
- end
424
-
425
- #Return array of lines surrounding the warning location from the original
426
- #file.
427
- def context_for app_tree, warning, tracker = nil
428
- file = file_for warning, tracker
429
- context = []
430
- return context unless warning.line and file and @app_tree.path_exists? file
431
-
432
- current_line = 0
433
- start_line = warning.line - 5
434
- end_line = warning.line + 5
435
-
436
- start_line = 1 if start_line < 0
437
-
438
- File.open file do |f|
439
- f.each_line do |line|
440
- current_line += 1
441
-
442
- next if line.strip == ""
443
-
444
- if current_line > end_line
445
- break
446
- end
447
-
448
- if current_line >= start_line
449
- context << [current_line, line]
450
- end
451
- end
452
- end
453
-
454
- context
455
- end
456
-
457
- def relative_path file
458
- pname = Pathname.new file
459
- if file and not file.empty? and pname.absolute?
460
- pname.relative_path_from(Pathname.new(@tracker.app_path)).to_s
461
- else
462
- file
463
- end
464
- end
465
-
466
349
  #Convert path/filename to view name
467
350
  #
468
351
  # views/test/something.html.erb -> test/something
469
352
  def template_path_to_name path
470
- names = path.split("/")
353
+ names = path.relative.split("/")
471
354
  names.last.gsub!(/(\.(html|js)\..*|\.(rhtml|haml|erb|slim))$/, '')
472
355
  names[(names.index("views") + 1)..-1].join("/").to_sym
473
356
  end
474
-
475
- def github_url file, line=nil
476
- if repo_url = @tracker.options[:github_url] and file and not file.empty? and file.start_with? '/'
477
- url = "#{repo_url}/#{relative_path(file)}"
478
- url << "#L#{line}" if line
479
- else
480
- nil
481
- end
482
- end
483
-
484
- def truncate_table str
485
- @terminal_width ||= if @tracker.options[:table_width]
486
- @tracker.options[:table_width]
487
- elsif $stdin && $stdin.tty?
488
- Brakeman.load_brakeman_dependency 'highline'
489
- ::HighLine.new.terminal_size[0]
490
- else
491
- 80
492
- end
493
- lines = str.lines
494
-
495
- lines.map do |line|
496
- if line.chomp.length > @terminal_width
497
- line[0..(@terminal_width - 3)] + ">>\n"
498
- else
499
- line
500
- end
501
- end.join
502
- end
503
357
  end
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "4.5.0"
2
+ Version = "4.5.1"
3
3
  end
@@ -9,7 +9,7 @@ class Brakeman::Warning
9
9
  :line, :method, :model, :template, :user_input, :user_input_type,
10
10
  :warning_code, :warning_set, :warning_type
11
11
 
12
- attr_accessor :code, :context, :file, :message, :relative_path
12
+ attr_accessor :code, :context, :file, :message
13
13
 
14
14
  TEXT_CONFIDENCE = {
15
15
  0 => "High",
@@ -34,11 +34,11 @@ class Brakeman::Warning
34
34
  :file => :@file,
35
35
  :gem_info => :@gem_info,
36
36
  :line => :@line,
37
+ :link => :@link,
37
38
  :link_path => :@link_path,
38
39
  :message => :@message,
39
40
  :method => :@method,
40
41
  :model => :@model,
41
- :relative_path => :@relative_path,
42
42
  :template => :@template,
43
43
  :user_input => :@user_input,
44
44
  :warning_set => :@warning_set,
@@ -100,9 +100,11 @@ class Brakeman::Warning
100
100
  unless @warning_set
101
101
  if self.model
102
102
  @warning_set = :model
103
+ @file ||= self.model.file
103
104
  elsif self.template
104
105
  @warning_set = :template
105
106
  @called_from = self.template.render_path
107
+ @file ||= self.template.file
106
108
  elsif self.controller
107
109
  @warning_set = :controller
108
110
  else
@@ -112,6 +114,8 @@ class Brakeman::Warning
112
114
 
113
115
  if options[:warning_code]
114
116
  @warning_code = Brakeman::WarningCodes.code options[:warning_code]
117
+ else
118
+ @warning_code = nil
115
119
  end
116
120
 
117
121
  Brakeman.debug("Warning created without warning code: #{options[:warning_code]}") unless @warning_code
@@ -221,7 +225,7 @@ class Brakeman::Warning
221
225
  when :template
222
226
  @row["Template"] = self.view_name.to_s
223
227
  when :model
224
- @row["Model"] = self.model.to_s
228
+ @row["Model"] = self.model.name.to_s
225
229
  when :controller
226
230
  @row["Controller"] = self.controller.to_s
227
231
  when :warning
@@ -235,7 +239,7 @@ class Brakeman::Warning
235
239
  def to_s
236
240
  output = "(#{TEXT_CONFIDENCE[self.confidence]}) #{self.warning_type} - #{self.message}"
237
241
  output << " near line #{self.line}" if self.line
238
- output << " in #{self.file}" if self.file
242
+ output << " in #{self.file.relative}" if self.file
239
243
  output << ": #{self.format_code}" if self.code
240
244
 
241
245
  output
@@ -247,37 +251,43 @@ class Brakeman::Warning
247
251
  warning_code_string = sprintf("%03d", @warning_code)
248
252
  code_string = @code.inspect
249
253
 
250
- Digest::SHA2.new(256).update("#{warning_code_string}#{code_string}#{location_string}#{@relative_path}#{self.confidence}").to_s
254
+ Digest::SHA2.new(256).update("#{warning_code_string}#{code_string}#{location_string}#{self.file.relative}#{self.confidence}").to_s
251
255
  end
252
256
 
253
257
  def location include_renderer = true
254
258
  case @warning_set
255
259
  when :template
256
- location = { :type => :template, :template => self.view_name(include_renderer) }
260
+ { :type => :template, :template => self.view_name(include_renderer) }
257
261
  when :model
258
- location = { :type => :model, :model => self.model }
262
+ { :type => :model, :model => self.model.name }
259
263
  when :controller
260
- location = { :type => :controller, :controller => self.controller }
264
+ { :type => :controller, :controller => self.controller }
261
265
  when :warning
262
266
  if self.class
263
- location = { :type => :method, :class => self.class, :method => self.method }
267
+ { :type => :method, :class => self.class, :method => self.method }
264
268
  else
265
- location = nil
269
+ nil
266
270
  end
267
271
  end
268
272
  end
269
273
 
270
- def to_hash
274
+ def to_hash absolute_paths: true
275
+ if self.called_from and not absolute_paths
276
+ render_path = self.called_from.with_relative_paths
277
+ else
278
+ render_path = self.called_from
279
+ end
280
+
271
281
  { :warning_type => self.warning_type,
272
282
  :warning_code => @warning_code,
273
283
  :fingerprint => self.fingerprint,
274
284
  :check_name => self.check.gsub(/^Brakeman::Check/, ''),
275
285
  :message => self.message.to_s,
276
- :file => self.file,
286
+ :file => (absolute_paths ? self.file.absolute : self.file.relative),
277
287
  :line => self.line,
278
288
  :link => self.link,
279
289
  :code => (@code && self.format_code(false)),
280
- :render_path => self.called_from,
290
+ :render_path => render_path,
281
291
  :location => self.location(false),
282
292
  :user_input => (@user_input && self.format_user_input(false)),
283
293
  :confidence => TEXT_CONFIDENCE[self.confidence]
@@ -110,6 +110,7 @@ module Brakeman::WarningCodes
110
110
  :CVE_2018_8048 => 106,
111
111
  :CVE_2018_3741 => 107,
112
112
  :CVE_2018_3760 => 108,
113
+ :force_ssl_disabled => 109,
113
114
  }
114
115
 
115
116
  def self.code name
@@ -45,6 +45,7 @@ class Brakeman::SexpProcessor
45
45
  @expected = Sexp
46
46
  @processors = self.class.processors
47
47
  @context = []
48
+ @current_class = @current_module = @current_method = @visibility = nil
48
49
 
49
50
  if @processors.empty?
50
51
  public_methods.each do |name|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman-lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.0
4
+ version: 4.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Collins
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
11
  - brakeman-public_cert.pem
12
- date: 2019-03-16 00:00:00.000000000 Z
12
+ date: 2019-05-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -39,6 +39,20 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: simplecov
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: ruby_parser
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -127,20 +141,14 @@ dependencies:
127
141
  name: highline
128
142
  requirement: !ruby/object:Gem::Requirement
129
143
  requirements:
130
- - - ">="
131
- - !ruby/object:Gem::Version
132
- version: 1.6.20
133
- - - "<"
144
+ - - "~>"
134
145
  - !ruby/object:Gem::Version
135
146
  version: '2.0'
136
147
  type: :runtime
137
148
  prerelease: false
138
149
  version_requirements: !ruby/object:Gem::Requirement
139
150
  requirements:
140
- - - ">="
141
- - !ruby/object:Gem::Version
142
- version: 1.6.20
143
- - - "<"
151
+ - - "~>"
144
152
  - !ruby/object:Gem::Version
145
153
  version: '2.0'
146
154
  - !ruby/object:Gem::Dependency
@@ -232,6 +240,7 @@ files:
232
240
  - lib/brakeman/checks/check_file_access.rb
233
241
  - lib/brakeman/checks/check_file_disclosure.rb
234
242
  - lib/brakeman/checks/check_filter_skipping.rb
243
+ - lib/brakeman/checks/check_force_ssl.rb
235
244
  - lib/brakeman/checks/check_forgery_setting.rb
236
245
  - lib/brakeman/checks/check_header_dos.rb
237
246
  - lib/brakeman/checks/check_i18n_xss.rb
@@ -289,6 +298,7 @@ files:
289
298
  - lib/brakeman/commandline.rb
290
299
  - lib/brakeman/differ.rb
291
300
  - lib/brakeman/file_parser.rb
301
+ - lib/brakeman/file_path.rb
292
302
  - lib/brakeman/format/style.css
293
303
  - lib/brakeman/messages.rb
294
304
  - lib/brakeman/options.rb