brakeman-min 3.1.5.pre1 → 3.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f7ed8514bb16d1d30d4f7b640dfbab79a6e8d034
4
- data.tar.gz: 460ed07d68c8a3af9eb3b2f5034310b29bc4bda5
3
+ metadata.gz: 7cb551015cbef2ba7f9fdc3c08b3ff4263116544
4
+ data.tar.gz: 667a81c5f75bccd9c39bfc4089f1261a601cf80d
5
5
  SHA512:
6
- metadata.gz: 6c986dcecf527e256507f89e60d93fb72c02f6c534cf04ca30412e05a07a8f5364928d3b1886b0787efdfbf2952d057d6e7dc45db4f89e9fe437fa7aafeeddf9
7
- data.tar.gz: 795321abc425629d277e8babc82d7d79e63ffe2bd0ab9da57f6e7451c3da1e6acfcd566932c78cd6f8c3c91ed69b787b93373a11e81d3dd6f6f9d97769eb3c1f
6
+ metadata.gz: 05a344e79c4b52d06d9e76c1875ac9a79aea718646caf1fef4a07e7d40d64609befd09db6733ba7630840f198db02ce4f0f4f4818dd7a9e4dd1f42d9ae9a36dd
7
+ data.tar.gz: a8307a36a59955e671753ebcb7776d22fd1cd5a7cdccb91654e99fc49f030805c603806efe47dbdf9b82bbc67bcf18f63ded4fe177ee546ff34887d363e0dc12
data/CHANGES CHANGED
@@ -1,14 +1,3 @@
1
- # 3.2.0.pre1
2
-
3
- * Support calls using `&.` operator
4
- * Update ruby_parser dependency to 3.8.1
5
- * Remove `fastercsv` dependency
6
- * Fix finding calls with `targets: nil`
7
- * Remove `multi-json` dependecy
8
- * Handle CoffeeScript in HAML
9
- * Avoid render warnings about params[:action]/params[:controller]
10
- * Index calls in class bodies but outside methods
11
-
12
1
  # 3.1.5
13
2
 
14
3
  * Fix CodeClimate construction of --only-files (Will Fleming)
@@ -407,20 +407,20 @@ module Brakeman
407
407
 
408
408
  # Compare JSON ouptut from a previous scan and return the diff of the two scans
409
409
  def self.compare options
410
- require 'json'
410
+ require 'multi_json'
411
411
  require 'brakeman/differ'
412
412
  raise ArgumentError.new("Comparison file doesn't exist") unless File.exist? options[:previous_results_json]
413
413
 
414
414
  begin
415
- previous_results = JSON.parse(File.read(options[:previous_results_json]), :symbolize_names => true)[:warnings]
416
- rescue JSON::ParserError
415
+ previous_results = MultiJson.load(File.read(options[:previous_results_json]), :symbolize_keys => true)[:warnings]
416
+ rescue MultiJson::DecodeError
417
417
  self.notify "Error parsing comparison file: #{options[:previous_results_json]}"
418
418
  exit!
419
419
  end
420
420
 
421
421
  tracker = run(options)
422
422
 
423
- new_results = JSON.parse(tracker.report.to_json, :symbolize_names => true)[:warnings]
423
+ new_results = MultiJson.load(tracker.report.to_json, :symbolize_keys => true)[:warnings]
424
424
 
425
425
  Brakeman::Differ.new(new_results, previous_results).diff
426
426
  end
@@ -5,8 +5,8 @@ class Brakeman::CallIndex
5
5
 
6
6
  #Initialize index with calls from FindAllCalls
7
7
  def initialize calls
8
- @calls_by_method = Hash.new { |h, k| h[k] = [] }
9
- @calls_by_target = Hash.new { |h, k| h[k] = [] }
8
+ @calls_by_method = Hash.new
9
+ @calls_by_target = Hash.new
10
10
 
11
11
  index_calls calls
12
12
  end
@@ -45,7 +45,7 @@ class Brakeman::CallIndex
45
45
 
46
46
  #Find calls with no explicit target
47
47
  #with either :target => nil or :target => false
48
- elsif (options.key? :target or options.key? :targets) and not target and method
48
+ elsif options.key? :target and not target and method
49
49
  calls = calls_by_method method
50
50
  calls = filter_by_target calls, nil
51
51
 
@@ -66,35 +66,44 @@ class Brakeman::CallIndex
66
66
  end
67
67
 
68
68
  def remove_template_indexes template_name = nil
69
- [@calls_by_method, @calls_by_target].each do |calls_by|
70
- calls_by.each do |name, calls|
71
- calls.delete_if do |call|
72
- from_template call, template_name
73
- end
69
+ @calls_by_method.each do |name, calls|
70
+ calls.delete_if do |call|
71
+ from_template call, template_name
72
+ end
73
+ end
74
+
75
+ @calls_by_target.each do |name, calls|
76
+ calls.delete_if do |call|
77
+ from_template call, template_name
74
78
  end
75
79
  end
76
80
  end
77
81
 
78
82
  def remove_indexes_by_class classes
79
- [@calls_by_method, @calls_by_target].each do |calls_by|
80
- calls_by.each do |name, calls|
81
- calls.delete_if do |call|
82
- call[:location][:type] == :class and classes.include? call[:location][:class]
83
- end
83
+ @calls_by_method.each do |name, calls|
84
+ calls.delete_if do |call|
85
+ call[:location][:type] == :class and classes.include? call[:location][:class]
86
+ end
87
+ end
88
+
89
+ @calls_by_target.each do |name, calls|
90
+ calls.delete_if do |call|
91
+ call[:location][:type] == :class and classes.include? call[:location][:class]
84
92
  end
85
93
  end
86
94
  end
87
95
 
88
96
  def index_calls calls
89
97
  calls.each do |call|
98
+ @calls_by_method[call[:method]] ||= []
90
99
  @calls_by_method[call[:method]] << call
91
100
 
92
- target = call[:target]
93
-
94
- if not target.is_a? Sexp
95
- @calls_by_target[target] << call
96
- elsif target.node_type == :params or target.node_type == :session
97
- @calls_by_target[target.node_type] << call
101
+ if not call[:target].is_a? Sexp
102
+ @calls_by_target[call[:target]] ||= []
103
+ @calls_by_target[call[:target]] << call
104
+ elsif call[:target].node_type == :params or call[:target].node_type == :session
105
+ @calls_by_target[call[:target].node_type] ||= []
106
+ @calls_by_target[call[:target].node_type] << call
98
107
  end
99
108
  end
100
109
  end
@@ -106,7 +115,7 @@ class Brakeman::CallIndex
106
115
  method = options[:method] || options[:methods]
107
116
 
108
117
  calls = calls_by_method method
109
-
118
+
110
119
  return [] if calls.nil?
111
120
 
112
121
  calls = filter_by_chain calls, target
@@ -136,7 +145,7 @@ class Brakeman::CallIndex
136
145
  elsif method.is_a? Regexp
137
146
  calls_by_methods_regex method
138
147
  else
139
- @calls_by_method[method.to_sym]
148
+ @calls_by_method[method.to_sym] || []
140
149
  end
141
150
  end
142
151
 
@@ -160,7 +169,7 @@ class Brakeman::CallIndex
160
169
  end
161
170
 
162
171
  def calls_with_no_target
163
- @calls_by_target[nil]
172
+ @calls_by_target[nil] || []
164
173
  end
165
174
 
166
175
  def filter calls, key, value
@@ -93,49 +93,91 @@ class Brakeman::Checks
93
93
  #Run all the checks on the given Tracker.
94
94
  #Returns a new instance of Checks with the results.
95
95
  def self.run_checks(app_tree, tracker)
96
- checks = self.checks_to_run(tracker)
96
+ if tracker.options[:parallel_checks]
97
+ self.run_checks_parallel(app_tree, tracker)
98
+ else
99
+ self.run_checks_sequential(app_tree, tracker)
100
+ end
101
+ end
102
+
103
+ #Run checks sequentially
104
+ def self.run_checks_sequential(app_tree, tracker)
97
105
  check_runner = self.new :min_confidence => tracker.options[:min_confidence]
98
- self.actually_run_checks(checks, check_runner, app_tree, tracker)
106
+
107
+ self.checks_to_run(tracker).each do |c|
108
+ check_name = get_check_name c
109
+
110
+ #Run or don't run check based on options
111
+ unless tracker.options[:skip_checks].include? check_name or
112
+ (tracker.options[:run_checks] and not tracker.options[:run_checks].include? check_name)
113
+
114
+ Brakeman.notify " - #{check_name}"
115
+
116
+ check = c.new(app_tree, tracker)
117
+
118
+ begin
119
+ check.run_check
120
+ rescue => e
121
+ tracker.error e
122
+ end
123
+
124
+ check.warnings.each do |w|
125
+ check_runner.add_warning w
126
+ end
127
+
128
+ #Maintain list of which checks were run
129
+ #mainly for reporting purposes
130
+ check_runner.checks_run << check_name[5..-1]
131
+ end
132
+ end
133
+
134
+ check_runner
99
135
  end
100
136
 
101
- def self.actually_run_checks(checks, check_runner, app_tree, tracker)
102
- threads = [] # Results for parallel
103
- results = [] # Results for sequential
104
- parallel = tracker.options[:parallel_checks]
137
+ #Run checks in parallel threads
138
+ def self.run_checks_parallel(app_tree, tracker)
139
+ threads = []
105
140
  error_mutex = Mutex.new
106
141
 
107
- checks.each do |c|
142
+ check_runner = self.new :min_confidence => tracker.options[:min_confidence]
143
+
144
+ self.checks_to_run(tracker).each do |c|
108
145
  check_name = get_check_name c
109
- Brakeman.notify " - #{check_name}"
110
146
 
111
- if parallel
147
+ #Run or don't run check based on options
148
+ unless tracker.options[:skip_checks].include? check_name or
149
+ (tracker.options[:run_checks] and not tracker.options[:run_checks].include? check_name)
150
+
151
+ Brakeman.notify " - #{check_name}"
152
+
112
153
  threads << Thread.new do
113
- self.run_a_check(c, error_mutex, app_tree, tracker)
154
+ check = c.new(app_tree, tracker)
155
+
156
+ begin
157
+ check.run_check
158
+ rescue => e
159
+ error_mutex.synchronize do
160
+ tracker.error e
161
+ end
162
+ end
163
+
164
+ check.warnings
114
165
  end
115
- else
116
- results << self.run_a_check(c, error_mutex, app_tree, tracker)
117
- end
118
166
 
119
- #Maintain list of which checks were run
120
- #mainly for reporting purposes
121
- check_runner.checks_run << check_name[5..-1]
167
+ #Maintain list of which checks were run
168
+ #mainly for reporting purposes
169
+ check_runner.checks_run << check_name[5..-1]
170
+ end
122
171
  end
123
172
 
124
173
  threads.each { |t| t.join }
125
174
 
126
175
  Brakeman.notify "Checks finished, collecting results..."
127
176
 
128
- if parallel
129
- threads.each do |thread|
130
- thread.value.each do |warning|
131
- check_runner.add_warning warning
132
- end
133
- end
134
- else
135
- results.each do |warnings|
136
- warnings.each do |warning|
137
- check_runner.add_warning warning
138
- end
177
+ #Collect results
178
+ threads.each do |thread|
179
+ thread.value.each do |warning|
180
+ check_runner.add_warning warning
139
181
  end
140
182
  end
141
183
 
@@ -149,39 +191,11 @@ class Brakeman::Checks
149
191
  end
150
192
 
151
193
  def self.checks_to_run tracker
152
- to_run = if tracker.options[:run_all_checks] or tracker.options[:run_checks]
153
- @checks + @optional_checks
154
- else
155
- @checks
156
- end
157
-
158
- self.filter_checks to_run, tracker
159
- end
160
-
161
- def self.filter_checks checks, tracker
162
- skipped = tracker.options[:skip_checks]
163
- explicit = tracker.options[:run_checks]
164
-
165
- checks.reject do |c|
166
- check_name = self.get_check_name(c)
167
-
168
- skipped.include? check_name or
169
- (explicit and not explicit.include? check_name)
170
- end
171
- end
172
-
173
- def self.run_a_check klass, mutex, app_tree, tracker
174
- check = klass.new(app_tree, tracker)
175
-
176
- begin
177
- check.run_check
178
- rescue => e
179
- mutex.synchronize do
180
- tracker.error e
181
- end
194
+ if tracker.options[:run_all_checks] or tracker.options[:run_checks]
195
+ @checks + @optional_checks
196
+ else
197
+ @checks
182
198
  end
183
-
184
- check.warnings
185
199
  end
186
200
  end
187
201
 
@@ -17,10 +17,31 @@ class Brakeman::CheckBasicAuthTimingAttack < Brakeman::BaseCheck
17
17
  return
18
18
  end
19
19
 
20
+ check_basic_auth_filter
20
21
  check_basic_auth_call
21
22
  end
22
23
 
24
+ def check_basic_auth_filter
25
+ controllers = tracker.controllers.select do |name, c|
26
+ c.options[:http_basic_authenticate_with]
27
+ end
28
+
29
+ Hash[controllers].each do |name, controller|
30
+ controller.options[:http_basic_authenticate_with].each do |call|
31
+ warn :controller => name,
32
+ :warning_type => "Timing Attack",
33
+ :warning_code => :CVE_2015_7576,
34
+ :message => "Basic authentication in Rails #{rails_version} is vulnerable to timing attacks. Upgrade to #@upgrade",
35
+ :code => call,
36
+ :confidence => CONFIDENCE[:high],
37
+ :file => controller.file,
38
+ :link => "https://groups.google.com/d/msg/rubyonrails-security/ANv0HDHEC3k/mt7wNGxbFQAJ"
39
+ end
40
+ end
41
+ end
42
+
23
43
  def check_basic_auth_call
44
+ # This is relatively unusual, but found in the wild
24
45
  tracker.find_call(target: nil, method: :http_basic_authenticate_with).each do |result|
25
46
  warn :result => result,
26
47
  :warning_type => "Timing Attack",
@@ -99,7 +99,7 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
99
99
  link_path = "cross_site_scripting"
100
100
  warning_code = :cross_site_scripting
101
101
 
102
- if node_type?(out, :call, :safe_call, :attrasgn, :safe_attrasgn) && out.method == :to_json
102
+ if node_type?(out, :call, :attrasgn) && out.method == :to_json
103
103
  message += " in JSON hash"
104
104
  link_path += "_to_json"
105
105
  warning_code = :xss_to_json
@@ -334,7 +334,7 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
334
334
  end
335
335
 
336
336
  def html_safe_call? exp
337
- call? exp.value and exp.value.method == :html_safe
337
+ exp.value.node_type == :call and exp.value.method == :html_safe
338
338
  end
339
339
 
340
340
  def ignore_call? target, method
@@ -35,6 +35,7 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
35
35
  if sexp? view and not duplicate? result
36
36
  add_result result
37
37
 
38
+
38
39
  if input = has_immediate_user_input?(view)
39
40
  if string_interp? view
40
41
  confidence = CONFIDENCE[:med]
@@ -48,7 +49,6 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
48
49
  end
49
50
 
50
51
  return if input.type == :model #skip models
51
- return if safe_param? input.match
52
52
 
53
53
  message = "Render path contains #{friendly_type_of input}"
54
54
 
@@ -71,7 +71,6 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
71
71
  if sexp? view and not duplicate? result
72
72
  if params? view
73
73
  add_result result
74
- return if safe_param? view
75
74
 
76
75
  warn :result => result,
77
76
  :warning_type => "Remote Code Execution",
@@ -82,11 +81,4 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
82
81
  end
83
82
  end
84
83
  end
85
-
86
- def safe_param? exp
87
- if params? exp and call? exp and exp.method == :[]
88
- arg = exp.first_arg
89
- symbol? arg and [:controller, :action].include? arg.value
90
- end
91
- end
92
84
  end
@@ -64,9 +64,9 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
64
64
  second_arg = args[2]
65
65
  next unless sexp? second_arg
66
66
 
67
- if second_arg.node_type == :iter and node_type? second_arg.block, :block, :call, :safe_call
67
+ if second_arg.node_type == :iter and node_type? second_arg.block, :block, :call
68
68
  process_scope_with_block(name, args)
69
- elsif call? second_arg
69
+ elsif second_arg.node_type == :call
70
70
  call = second_arg
71
71
  scope_calls << scope_call_hash(call, name, call.method)
72
72
  else
@@ -107,7 +107,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
107
107
  find_calls = Brakeman::FindAllCalls.new(tracker)
108
108
  find_calls.process_source(block, :class => model_name, :method => scope_name)
109
109
  find_calls.calls.each { |call| process_result(call) if @sql_targets.include?(call[:method]) }
110
- elsif call? block
110
+ elsif block.node_type == :call
111
111
  while call? block
112
112
  process_result :target => block.target, :method => block.method, :call => block,
113
113
  :location => { :type => :class, :class => model_name, :method => scope_name }
@@ -296,7 +296,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
296
296
 
297
297
  # Handles x = y = z = 1
298
298
  def get_rhs exp
299
- if node_type? exp, :lasgn, :iasgn, :gasgn, :attrasgn, :safe_attrasgn, :cvdecl, :cdecl
299
+ if node_type? exp, :lasgn, :iasgn, :gasgn, :attrasgn, :cvdecl, :cdecl
300
300
  get_rhs(exp.rhs)
301
301
  else
302
302
  exp
@@ -68,14 +68,6 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
68
68
  call
69
69
  end
70
70
 
71
- def process_safe_call exp
72
- if self.respond_to? :process_call
73
- process_call exp
74
- else
75
- process_default exp
76
- end
77
- end
78
-
79
71
  #String with interpolation.
80
72
  def process_dstr exp
81
73
  exp = exp.dup
@@ -25,7 +25,7 @@ class Brakeman::ErbTemplateProcessor < Brakeman::TemplateProcessor
25
25
 
26
26
  arg = exp.first_arg
27
27
 
28
- if call? arg and arg.method == :to_s #erb always calls to_s on output
28
+ if arg.node_type == :call and arg.method == :to_s #erb always calls to_s on output
29
29
  arg = arg.target
30
30
  end
31
31
 
@@ -21,7 +21,7 @@ class Brakeman::ErubisTemplateProcessor < Brakeman::TemplateProcessor
21
21
  arg = exp.first_arg
22
22
 
23
23
  #We want the actual content
24
- if call? arg and (arg.method == :to_s or arg.method == :html_safe!)
24
+ if arg.node_type == :call and (arg.method == :to_s or arg.method == :html_safe!)
25
25
  arg = arg.target
26
26
  end
27
27
 
@@ -5,7 +5,6 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
5
5
  HAML_FORMAT_METHOD = /format_script_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)/
6
6
  HAML_HELPERS = s(:colon2, s(:const, :Haml), :Helpers)
7
7
  JAVASCRIPT_FILTER = s(:colon2, s(:colon2, s(:const, :Haml), :Filters), :Javascript)
8
- COFFEE_FILTER = s(:colon2, s(:colon2, s(:const, :Haml), :Filters), :Coffee)
9
8
 
10
9
  #Processes call, looking for template output
11
10
  def process_call exp
@@ -91,7 +90,7 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
91
90
  elsif target == nil and method == :find_and_preserve
92
91
  process exp.first_arg
93
92
  elsif method == :render_with_options
94
- if target == JAVASCRIPT_FILTER or target == COFFEE_FILTER
93
+ if target == JAVASCRIPT_FILTER
95
94
  @javascript = true
96
95
  end
97
96
 
@@ -14,20 +14,4 @@ class Brakeman::BasicProcessor < Brakeman::SexpProcessor
14
14
  def process_default exp
15
15
  process_all exp
16
16
  end
17
-
18
- def process_safe_call exp
19
- if self.respond_to? :process_call
20
- process_call exp
21
- else
22
- process_default exp
23
- end
24
- end
25
-
26
- def process_safe_attrasgn exp
27
- if self.respond_to? :process_attrasgn
28
- process_attrasgn exp
29
- else
30
- process_default exp
31
- end
32
- end
33
17
  end
@@ -24,13 +24,11 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
24
24
 
25
25
  #Process body of method
26
26
  def process_defn exp
27
- return exp unless @current_method
28
27
  process_all exp.body
29
28
  end
30
29
 
31
30
  #Process body of method
32
31
  def process_defs exp
33
- return exp unless @current_method
34
32
  process_all exp.body
35
33
  end
36
34
 
@@ -141,7 +139,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
141
139
  @current_class || @current_module || nil
142
140
  when :params, :session, :cookies
143
141
  exp.node_type
144
- when :call, :safe_call
142
+ when :call
145
143
  if include_calls
146
144
  if exp.target.nil?
147
145
  exp.method
@@ -167,7 +165,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
167
165
  #Returns method chain as an array
168
166
  #For example, User.human.alive.all would return [:User, :human, :alive, :all]
169
167
  def get_chain call
170
- if node_type? call, :call, :attrasgn, :safe_call, :safe_attrasgn
168
+ if node_type? call, :call, :attrasgn
171
169
  get_chain(call.target) + [call.method]
172
170
  elsif call.nil?
173
171
  []
@@ -102,7 +102,7 @@ class Brakeman::FindCall < Brakeman::BasicProcessor
102
102
  # User.find(:first, :conditions => "user = '#{params['user']}').name
103
103
  #
104
104
  #A search for User.find will not match this unless @in_depth is true.
105
- if @in_depth and call? exp.target
105
+ if @in_depth and node_type? exp.target, :call
106
106
  process exp.target
107
107
  end
108
108
 
@@ -95,8 +95,7 @@ module Brakeman
95
95
  end
96
96
 
97
97
  def to_json *args
98
- require 'json'
99
- JSON.generate(@path)
98
+ MultiJson.dump(@path)
100
99
  end
101
100
 
102
101
  def initialize_copy original
@@ -1,5 +1,5 @@
1
1
  require 'set'
2
- require 'json'
2
+ require 'multi_json'
3
3
 
4
4
  module Brakeman
5
5
  class IgnoreConfig
@@ -75,7 +75,7 @@ module Brakeman
75
75
  # Read configuration to file
76
76
  def read_from_file file = @file
77
77
  if File.exist? file
78
- @already_ignored = JSON.parse(File.read(file), :symbolize_names => true)[:ignored_warnings]
78
+ @already_ignored = MultiJson.load(File.read(file), :symbolize_keys => true)[:ignored_warnings]
79
79
  else
80
80
  Brakeman.notify "[Notice] Could not find ignore configuration in #{file}"
81
81
  @already_ignored = []
@@ -107,7 +107,7 @@ module Brakeman
107
107
  }
108
108
 
109
109
  File.open file, "w" do |f|
110
- f.puts JSON.pretty_generate(output)
110
+ f.puts MultiJson.dump(output, :pretty => true)
111
111
  end
112
112
  end
113
113
 
@@ -0,0 +1,7 @@
1
+ # Ruby 1.8 compatible
2
+ if CSV.const_defined? :Reader
3
+ require 'fastercsv'
4
+ Object.send(:remove_const, :CSV)
5
+ CSV = FasterCSV
6
+ end
7
+
@@ -0,0 +1,29 @@
1
+ #MultiJson interface changed in 1.3.0, but need
2
+ #to support older MultiJson for Rails 3.1.
3
+ mj_engine = nil
4
+
5
+ if MultiJson.respond_to? :default_adapter
6
+ mj_engine = MultiJson.default_adapter
7
+ else
8
+ mj_engine = MultiJson.default_engine
9
+
10
+ module MultiJson
11
+ def self.dump *args
12
+ encode *args
13
+ end
14
+
15
+ def self.load *args
16
+ decode *args
17
+ end
18
+ end
19
+ end
20
+
21
+ #This is so OkJson will work with symbol values
22
+ if mj_engine == :ok_json
23
+ class Symbol
24
+ def to_json
25
+ self.to_s.inspect
26
+ end
27
+ end
28
+ end
29
+
@@ -1,4 +1,5 @@
1
- require 'csv'
1
+ Brakeman.load_brakeman_dependency 'csv'
2
+ require "brakeman/report/initializers/faster_csv"
2
3
  require "brakeman/report/report_table"
3
4
 
4
5
  class Brakeman::Report::CSV < Brakeman::Report::Table
@@ -1,3 +1,6 @@
1
+ Brakeman.load_brakeman_dependency 'multi_json'
2
+ require 'brakeman/report/initializers/multi_json'
3
+
1
4
  class Brakeman::Report::JSON < Brakeman::Report::Base
2
5
  def generate_report
3
6
  errors = tracker.errors.map{|e| { :error => e[:error], :location => e[:backtrace][0] }}
@@ -29,7 +32,7 @@ class Brakeman::Report::JSON < Brakeman::Report::Base
29
32
  :errors => errors
30
33
  }
31
34
 
32
- JSON.pretty_generate report_info
35
+ MultiJson.dump(report_info, :pretty => true)
33
36
  end
34
37
 
35
38
  def convert_to_hashes warnings
@@ -115,23 +115,6 @@ class Brakeman::Tracker
115
115
  end
116
116
  end
117
117
 
118
-
119
- def each_class
120
- classes = [self.controllers, self.models]
121
-
122
- if @options[:index_libs]
123
- classes << self.libs
124
- end
125
-
126
- classes.each do |set|
127
- set.each do |set_name, collection|
128
- collection.src.each do |file, src|
129
- yield src, set_name, file
130
- end
131
- end
132
- end
133
- end
134
-
135
118
  #Find a method call.
136
119
  #
137
120
  #Options:
@@ -195,10 +178,6 @@ class Brakeman::Tracker
195
178
  finder.process_source definition, :class => set_name, :method => method_name, :file => file
196
179
  end
197
180
 
198
- self.each_class do |definition, set_name, file|
199
- finder.process_source definition, :class => set_name, :file => file
200
- end
201
-
202
181
  self.each_template do |name, template|
203
182
  finder.process_source template.src, :template => template, :file => template.file
204
183
  end
@@ -167,8 +167,7 @@ module Brakeman::Util
167
167
 
168
168
  #Check if _exp_ represents a method call: s(:call, ...)
169
169
  def call? exp
170
- exp.is_a? Sexp and
171
- (exp.node_type == :call or exp.node_type == :safe_call)
170
+ exp.is_a? Sexp and exp.node_type == :call
172
171
  end
173
172
 
174
173
  #Check if _exp_ represents a Regexp: s(:lit, /.../)
@@ -215,7 +214,7 @@ module Brakeman::Util
215
214
  if exp.is_a? Sexp
216
215
  return true if exp.node_type == :params or ALL_PARAMETERS.include? exp
217
216
 
218
- if call? exp
217
+ if exp.node_type == :call
219
218
  if params? exp[1]
220
219
  return true
221
220
  elsif exp[2] == :[]
@@ -231,7 +230,7 @@ module Brakeman::Util
231
230
  if exp.is_a? Sexp
232
231
  return true if exp.node_type == :cookies or exp == COOKIES
233
232
 
234
- if call? exp
233
+ if exp.node_type == :call
235
234
  if cookies? exp[1]
236
235
  return true
237
236
  elsif exp[2] == :[]
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "3.1.5.pre1"
2
+ Version = "3.1.5"
3
3
  end
@@ -1,4 +1,4 @@
1
- require 'json'
1
+ require 'multi_json'
2
2
  require 'digest/sha2'
3
3
  require 'brakeman/warning_codes'
4
4
 
@@ -241,7 +241,7 @@ class Brakeman::Warning
241
241
  end
242
242
 
243
243
  def to_json
244
- JSON.generate self.to_hash
244
+ MultiJson.dump self.to_hash
245
245
  end
246
246
 
247
247
  private
@@ -141,13 +141,13 @@ class Sexp
141
141
  #s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1)))
142
142
  # ^-----------target-----------^
143
143
  def target
144
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
144
+ expect :call, :attrasgn
145
145
  self[1]
146
146
  end
147
147
 
148
148
  #Sets the target of a method call:
149
149
  def target= exp
150
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
150
+ expect :call, :attrasgn
151
151
  @my_hash_value = nil
152
152
  self[1] = exp
153
153
  end
@@ -157,10 +157,10 @@ class Sexp
157
157
  #s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1)))
158
158
  # ^- method
159
159
  def method
160
- expect :call, :attrasgn, :safe_call, :safe_attrasgn, :super, :zsuper, :result
160
+ expect :call, :attrasgn, :super, :zsuper, :result
161
161
 
162
162
  case self.node_type
163
- when :call, :attrasgn, :safe_call, :safe_attrasgn
163
+ when :call, :attrasgn
164
164
  self[2]
165
165
  when :super, :zsuper
166
166
  :super
@@ -170,14 +170,14 @@ class Sexp
170
170
  end
171
171
 
172
172
  def method= name
173
- expect :call, :safe_call
173
+ expect :call
174
174
 
175
175
  self[2] = name
176
176
  end
177
177
 
178
178
  #Sets the arglist in a method call.
179
179
  def arglist= exp
180
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
180
+ expect :call, :attrasgn
181
181
  @my_hash_value = nil
182
182
  start_index = 3
183
183
 
@@ -201,10 +201,10 @@ class Sexp
201
201
  # s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1), s(:lit, 2)))
202
202
  # ^------------ arglist ------------^
203
203
  def arglist
204
- expect :call, :attrasgn, :safe_call, :safe_attrasgn, :super, :zsuper
204
+ expect :call, :attrasgn, :super, :zsuper
205
205
 
206
206
  case self.node_type
207
- when :call, :attrasgn, :safe_call, :safe_attrasgn
207
+ when :call, :attrasgn
208
208
  self[3..-1].unshift :arglist
209
209
  when :super, :zsuper
210
210
  if self[1]
@@ -220,10 +220,10 @@ class Sexp
220
220
  # s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1), s(:lit, 2)))
221
221
  # ^--------args--------^
222
222
  def args
223
- expect :call, :attrasgn, :safe_call, :safe_attrasgn, :super, :zsuper
223
+ expect :call, :attrasgn, :super, :zsuper
224
224
 
225
225
  case self.node_type
226
- when :call, :attrasgn, :safe_call, :safe_attrasgn
226
+ when :call, :attrasgn
227
227
  if self[3]
228
228
  self[3..-1]
229
229
  else
@@ -239,11 +239,11 @@ class Sexp
239
239
  end
240
240
 
241
241
  def each_arg replace = false
242
- expect :call, :attrasgn, :safe_call, :safe_attrasgn, :super, :zsuper
242
+ expect :call, :attrasgn, :super, :zsuper
243
243
  range = nil
244
244
 
245
245
  case self.node_type
246
- when :call, :attrasgn, :safe_call, :safe_attrasgn
246
+ when :call, :attrasgn
247
247
  if self[3]
248
248
  range = (3...self.length)
249
249
  end
@@ -270,43 +270,43 @@ class Sexp
270
270
 
271
271
  #Returns first argument of a method call.
272
272
  def first_arg
273
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
273
+ expect :call, :attrasgn
274
274
  self[3]
275
275
  end
276
276
 
277
277
  #Sets first argument of a method call.
278
278
  def first_arg= exp
279
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
279
+ expect :call, :attrasgn
280
280
  @my_hash_value = nil
281
281
  self[3] = exp
282
282
  end
283
283
 
284
284
  #Returns second argument of a method call.
285
285
  def second_arg
286
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
286
+ expect :call, :attrasgn
287
287
  self[4]
288
288
  end
289
289
 
290
290
  #Sets second argument of a method call.
291
291
  def second_arg= exp
292
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
292
+ expect :call, :attrasgn
293
293
  @my_hash_value = nil
294
294
  self[4] = exp
295
295
  end
296
296
 
297
297
  def third_arg
298
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
298
+ expect :call, :attrasgn
299
299
  self[5]
300
300
  end
301
301
 
302
302
  def third_arg= exp
303
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
303
+ expect :call, :attrasgn
304
304
  @my_hash_value = nil
305
305
  self[5] = exp
306
306
  end
307
307
 
308
308
  def last_arg
309
- expect :call, :attrasgn, :safe_call, :safe_attrasgn
309
+ expect :call, :attrasgn
310
310
 
311
311
  if self[3]
312
312
  self[-1]
@@ -427,9 +427,9 @@ class Sexp
427
427
  # s(:lasgn, :x, s(:lit, 1))
428
428
  # ^--rhs---^
429
429
  def rhs
430
- expect :attrasgn, :safe_attrasgn, *ASSIGNMENT_BOOL
430
+ expect :attrasgn, *ASSIGNMENT_BOOL
431
431
 
432
- if self.node_type == :attrasgn or self.node_type == :safe_attrasgn
432
+ if self.node_type == :attrasgn
433
433
  self[3]
434
434
  else
435
435
  self[2]
@@ -438,10 +438,10 @@ class Sexp
438
438
 
439
439
  #Sets the right hand side of assignment or boolean.
440
440
  def rhs= exp
441
- expect :attrasgn, :safe_attrasgn, *ASSIGNMENT_BOOL
441
+ expect :attrasgn, *ASSIGNMENT_BOOL
442
442
  @my_hash_value = nil
443
443
 
444
- if self.node_type == :attrasgn or self.node_type == :safe_attrasgn
444
+ if self.node_type == :attrasgn
445
445
  self[3] = exp
446
446
  else
447
447
  self[2] = exp
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman-min
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.5.pre1
4
+ version: 3.1.5
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: 2016-02-22 00:00:00.000000000 Z
12
+ date: 2016-01-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: test-unit
@@ -31,28 +31,48 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 3.8.1
34
+ version: 3.7.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 3.8.1
41
+ version: 3.7.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: ruby2ruby
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - "~>"
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 2.1.1
49
+ - - "<"
47
50
  - !ruby/object:Gem::Version
48
51
  version: 2.3.0
49
52
  type: :runtime
50
53
  prerelease: false
51
54
  version_requirements: !ruby/object:Gem::Requirement
52
55
  requirements:
53
- - - "~>"
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 2.1.1
59
+ - - "<"
54
60
  - !ruby/object:Gem::Version
55
61
  version: 2.3.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: multi_json
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ type: :runtime
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.2'
56
76
  - !ruby/object:Gem::Dependency
57
77
  name: safe_yaml
58
78
  requirement: !ruby/object:Gem::Requirement
@@ -194,6 +214,8 @@ files:
194
214
  - lib/brakeman/report/config/remediation.yml
195
215
  - lib/brakeman/report/ignore/config.rb
196
216
  - lib/brakeman/report/ignore/interactive.rb
217
+ - lib/brakeman/report/initializers/faster_csv.rb
218
+ - lib/brakeman/report/initializers/multi_json.rb
197
219
  - lib/brakeman/report/renderer.rb
198
220
  - lib/brakeman/report/report_base.rb
199
221
  - lib/brakeman/report/report_codeclimate.rb
@@ -245,9 +267,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
245
267
  version: '0'
246
268
  required_rubygems_version: !ruby/object:Gem::Requirement
247
269
  requirements:
248
- - - ">"
270
+ - - ">="
249
271
  - !ruby/object:Gem::Version
250
- version: 1.3.1
272
+ version: '0'
251
273
  requirements: []
252
274
  rubyforge_project:
253
275
  rubygems_version: 2.4.8