brakeman 1.2.1 → 1.2.2

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/lib/brakeman.rb CHANGED
@@ -48,7 +48,9 @@ module Brakeman
48
48
  @quiet = !!options[:quiet]
49
49
  @debug = !!options[:debug]
50
50
 
51
- options[:report_progress] = !@quiet
51
+ if @quiet
52
+ options[:report_progress] = false
53
+ end
52
54
 
53
55
  scan options
54
56
  end
@@ -44,12 +44,6 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
44
44
  @models = tracker.models.keys
45
45
  @inspect_arguments = tracker.options[:check_arguments]
46
46
 
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
52
-
53
47
  @known_dangerous = Set.new([:truncate, :concat])
54
48
 
55
49
  if version_between? "2.0.0", "3.0.5"
@@ -264,121 +258,3 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
264
258
  exp[1].node_type == :call and exp[1][2] == :raw
265
259
  end
266
260
  end
267
-
268
- #This _only_ checks calls to link_to
269
- class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
270
- def run_check
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
-
279
- @known_dangerous = []
280
- #Ideally, I think this should also check to see if people are setting
281
- #:escape => false
282
- methods = tracker.find_call :target => false, :method => :link_to
283
-
284
- @models = tracker.models.keys
285
- @inspect_arguments = tracker.options[:check_arguments]
286
-
287
- methods.each do |call|
288
- process_result call
289
- end
290
- end
291
-
292
- def process_result result
293
- #Have to make a copy of this, otherwise it will be changed to
294
- #an ignored method call by the code above.
295
- call = result[:call] = result[:call].dup
296
-
297
- @matched = false
298
-
299
- return if call[3][1].nil?
300
-
301
- #Only check first argument for +link_to+, as the second
302
- #will *usually* be a record or escaped.
303
- first_arg = process call[3][1]
304
-
305
- type, match = has_immediate_user_input? first_arg
306
-
307
- if type
308
- case type
309
- when :params
310
- message = "Unescaped parameter value in link_to"
311
- when :cookies
312
- message = "Unescaped cookie value in link_to"
313
- else
314
- message = "Unescaped user input value in link_to"
315
- end
316
-
317
- unless duplicate? result
318
- add_result result
319
-
320
- warn :result => result,
321
- :warning_type => "Cross Site Scripting",
322
- :message => message,
323
- :confidence => CONFIDENCE[:high]
324
- end
325
-
326
- elsif not tracker.options[:ignore_model_output] and match = has_immediate_model?(first_arg)
327
- method = match[2]
328
-
329
- unless duplicate? result or IGNORE_MODEL_METHODS.include? method
330
- add_result result
331
-
332
- if MODEL_METHODS.include? method or method.to_s =~ /^find_by/
333
- confidence = CONFIDENCE[:high]
334
- else
335
- confidence = CONFIDENCE[:med]
336
- end
337
-
338
- warn :result => result,
339
- :warning_type => "Cross Site Scripting",
340
- :message => "Unescaped model attribute in link_to",
341
- :confidence => confidence
342
- end
343
-
344
- elsif @matched
345
- if @matched == :model and not tracker.options[:ignore_model_output]
346
- message = "Unescaped model attribute in link_to"
347
- elsif @matched == :params
348
- message = "Unescaped parameter value in link_to"
349
- end
350
-
351
- if message and not duplicate? result
352
- add_result result
353
-
354
- warn :result => result,
355
- :warning_type => "Cross Site Scripting",
356
- :message => message,
357
- :confidence => CONFIDENCE[:med]
358
- end
359
- end
360
- end
361
-
362
- def process_call exp
363
- @mark = true
364
- actually_process_call exp
365
- exp
366
- end
367
-
368
- def actually_process_call exp
369
- return if @matched
370
-
371
- target = exp[1]
372
- if sexp? target
373
- target = process target.dup
374
- end
375
-
376
- #Bare records create links to the model resource,
377
- #not a string that could have injection
378
- if model_name? target and context == [:call, :arglist]
379
- return exp
380
- end
381
-
382
- super
383
- end
384
- end
@@ -0,0 +1,126 @@
1
+ require 'brakeman/checks/check_cross_site_scripting'
2
+
3
+ #Checks for calls to link_to in versions of Ruby where link_to did not
4
+ #escape the first argument.
5
+ #
6
+ #See https://rails.lighthouseapp.com/projects/8994/tickets/3518-link_to-doesnt-escape-its-input
7
+ class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
8
+ Brakeman::Checks.add self
9
+
10
+ def run_check
11
+ return unless version_between?("2.0.0", "2.9.9") and not tracker.config[:escape_html]
12
+
13
+ @ignore_methods = Set.new([:button_to, :check_box, :escapeHTML, :escape_once,
14
+ :field_field, :fields_for, :h, :hidden_field,
15
+ :hidden_field, :hidden_field_tag, :image_tag, :label,
16
+ :mail_to, :radio_button, :select,
17
+ :submit_tag, :text_area, :text_field,
18
+ :text_field_tag, :url_encode, :url_for,
19
+ :will_paginate] ).merge tracker.options[:safe_methods]
20
+
21
+ @known_dangerous = []
22
+ #Ideally, I think this should also check to see if people are setting
23
+ #:escape => false
24
+ methods = tracker.find_call :target => false, :method => :link_to
25
+
26
+ @models = tracker.models.keys
27
+ @inspect_arguments = tracker.options[:check_arguments]
28
+
29
+ methods.each do |call|
30
+ process_result call
31
+ end
32
+ end
33
+
34
+ def process_result result
35
+ #Have to make a copy of this, otherwise it will be changed to
36
+ #an ignored method call by the code above.
37
+ call = result[:call] = result[:call].dup
38
+
39
+ @matched = false
40
+
41
+ return if call[3][1].nil?
42
+
43
+ #Only check first argument for +link_to+, as the second
44
+ #will *usually* be a record or escaped.
45
+ first_arg = process call[3][1]
46
+
47
+ type, match = has_immediate_user_input? first_arg
48
+
49
+ if type
50
+ case type
51
+ when :params
52
+ message = "Unescaped parameter value in link_to"
53
+ when :cookies
54
+ message = "Unescaped cookie value in link_to"
55
+ else
56
+ message = "Unescaped user input value in link_to"
57
+ end
58
+
59
+ unless duplicate? result
60
+ add_result result
61
+
62
+ warn :result => result,
63
+ :warning_type => "Cross Site Scripting",
64
+ :message => message,
65
+ :confidence => CONFIDENCE[:high]
66
+ end
67
+
68
+ elsif not tracker.options[:ignore_model_output] and match = has_immediate_model?(first_arg)
69
+ method = match[2]
70
+
71
+ unless duplicate? result or IGNORE_MODEL_METHODS.include? method
72
+ add_result result
73
+
74
+ if MODEL_METHODS.include? method or method.to_s =~ /^find_by/
75
+ confidence = CONFIDENCE[:high]
76
+ else
77
+ confidence = CONFIDENCE[:med]
78
+ end
79
+
80
+ warn :result => result,
81
+ :warning_type => "Cross Site Scripting",
82
+ :message => "Unescaped model attribute in link_to",
83
+ :confidence => confidence
84
+ end
85
+
86
+ elsif @matched
87
+ if @matched == :model and not tracker.options[:ignore_model_output]
88
+ message = "Unescaped model attribute in link_to"
89
+ elsif @matched == :params
90
+ message = "Unescaped parameter value in link_to"
91
+ end
92
+
93
+ if message and not duplicate? result
94
+ add_result result
95
+
96
+ warn :result => result,
97
+ :warning_type => "Cross Site Scripting",
98
+ :message => message,
99
+ :confidence => CONFIDENCE[:med]
100
+ end
101
+ end
102
+ end
103
+
104
+ def process_call exp
105
+ @mark = true
106
+ actually_process_call exp
107
+ exp
108
+ end
109
+
110
+ def actually_process_call exp
111
+ return if @matched
112
+
113
+ target = exp[1]
114
+ if sexp? target
115
+ target = process target.dup
116
+ end
117
+
118
+ #Bare records create links to the model resource,
119
+ #not a string that could have injection
120
+ if model_name? target and context == [:call, :arglist]
121
+ return exp
122
+ end
123
+
124
+ super
125
+ end
126
+ end
@@ -69,7 +69,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
69
69
  process_namespace exp
70
70
  when :resources, :resource
71
71
  process_resources exp[1][3][1..-1]
72
- process_default exp[3]
72
+ process_default exp[3] if exp[3]
73
73
  when :with_options
74
74
  process_with_options exp
75
75
  end
@@ -111,7 +111,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
111
111
  hash_iterate(exp) do |option, value|
112
112
  case option[1]
113
113
  when :controller, :requirements, :singular, :path_prefix, :as,
114
- :path_names, :shallow, :name_prefix
114
+ :path_names, :shallow, :name_prefix, :member_path, :nested_member_path
115
115
  #should be able to skip
116
116
  when :collection, :member, :new
117
117
  process_collection value
@@ -128,7 +128,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
128
128
  when :except
129
129
  process_option_except value
130
130
  else
131
- raise "Unhandled resource option: #{option}"
131
+ Brakeman.notify "[Notice] Unhandled resource option: #{option}"
132
132
  end
133
133
  end
134
134
  end
@@ -245,6 +245,14 @@ class Brakeman::RescanReport
245
245
  @diff ||= @new_results.diff(@old_results)
246
246
  end
247
247
 
248
+ #Returns an array of warnings which were in the old report and the new report
249
+ def existing_warnings
250
+ @old ||= all_warnings.select do |w|
251
+ not new_warnings.include? w
252
+ end
253
+ end
254
+
255
+ #Output total, fixed, and new warnings
248
256
  def to_s
249
257
  <<-OUTPUT
250
258
  Total warnings: #{all_warnings.length}
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "1.2.1"
2
+ Version = "1.2.2"
3
3
  end
metadata CHANGED
@@ -1,101 +1,127 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: brakeman
3
- version: !ruby/object:Gem::Version
4
- version: 1.2.1
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 2
8
+ - 2
9
+ version: 1.2.2
6
10
  platform: ruby
7
- authors:
11
+ authors:
8
12
  - Justin Collins
9
13
  autorequire:
10
14
  bindir: bin
11
15
  cert_chain: []
12
- date: 2012-01-20 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
16
+
17
+ date: 2012-01-26 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: activesupport
16
- requirement: &76221240 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
22
31
  type: :runtime
23
- prerelease: false
24
- version_requirements: *76221240
25
- - !ruby/object:Gem::Dependency
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
26
34
  name: i18n
27
- requirement: &76220920 !ruby/object:Gem::Requirement
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
28
37
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
33
44
  type: :runtime
34
- prerelease: false
35
- version_requirements: *76220920
36
- - !ruby/object:Gem::Dependency
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
37
47
  name: ruby2ruby
38
- requirement: &76220320 !ruby/object:Gem::Requirement
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
39
50
  none: false
40
- requirements:
51
+ requirements:
41
52
  - - ~>
42
- - !ruby/object:Gem::Version
43
- version: '1.2'
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 1
56
+ - 2
57
+ version: "1.2"
44
58
  type: :runtime
45
- prerelease: false
46
- version_requirements: *76220320
47
- - !ruby/object:Gem::Dependency
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
48
61
  name: ruport
49
- requirement: &76219720 !ruby/object:Gem::Requirement
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
50
64
  none: false
51
- requirements:
65
+ requirements:
52
66
  - - ~>
53
- - !ruby/object:Gem::Version
54
- version: '1.6'
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 1
70
+ - 6
71
+ version: "1.6"
55
72
  type: :runtime
56
- prerelease: false
57
- version_requirements: *76219720
58
- - !ruby/object:Gem::Dependency
73
+ version_requirements: *id004
74
+ - !ruby/object:Gem::Dependency
59
75
  name: erubis
60
- requirement: &76943790 !ruby/object:Gem::Requirement
76
+ prerelease: false
77
+ requirement: &id005 !ruby/object:Gem::Requirement
61
78
  none: false
62
- requirements:
79
+ requirements:
63
80
  - - ~>
64
- - !ruby/object:Gem::Version
65
- version: '2.6'
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 2
84
+ - 6
85
+ version: "2.6"
66
86
  type: :runtime
67
- prerelease: false
68
- version_requirements: *76943790
69
- - !ruby/object:Gem::Dependency
87
+ version_requirements: *id005
88
+ - !ruby/object:Gem::Dependency
70
89
  name: haml
71
- requirement: &76943560 !ruby/object:Gem::Requirement
90
+ prerelease: false
91
+ requirement: &id006 !ruby/object:Gem::Requirement
72
92
  none: false
73
- requirements:
93
+ requirements:
74
94
  - - ~>
75
- - !ruby/object:Gem::Version
76
- version: '3.0'
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 3
98
+ - 0
99
+ version: "3.0"
77
100
  type: :runtime
78
- prerelease: false
79
- version_requirements: *76943560
80
- - !ruby/object:Gem::Dependency
101
+ version_requirements: *id006
102
+ - !ruby/object:Gem::Dependency
81
103
  name: sass
82
- requirement: &76943330 !ruby/object:Gem::Requirement
104
+ prerelease: false
105
+ requirement: &id007 !ruby/object:Gem::Requirement
83
106
  none: false
84
- requirements:
107
+ requirements:
85
108
  - - ~>
86
- - !ruby/object:Gem::Version
87
- version: '3.0'
109
+ - !ruby/object:Gem::Version
110
+ segments:
111
+ - 3
112
+ - 0
113
+ version: "3.0"
88
114
  type: :runtime
89
- prerelease: false
90
- version_requirements: *76943330
91
- description: Brakeman detects security vulnerabilities in Ruby on Rails applications
92
- via static analysis.
115
+ version_requirements: *id007
116
+ description: Brakeman detects security vulnerabilities in Ruby on Rails applications via static analysis.
93
117
  email:
94
- executables:
118
+ executables:
95
119
  - brakeman
96
120
  extensions: []
121
+
97
122
  extra_rdoc_files: []
98
- files:
123
+
124
+ files:
99
125
  - bin/brakeman
100
126
  - WARNING_TYPES
101
127
  - FEATURES
@@ -147,6 +173,7 @@ files:
147
173
  - lib/brakeman/checks/check_evaluation.rb
148
174
  - lib/brakeman/checks/check_quote_table_name.rb
149
175
  - lib/brakeman/checks/check_validation_regex.rb
176
+ - lib/brakeman/checks/check_link_to.rb
150
177
  - lib/brakeman/checks/check_execute.rb
151
178
  - lib/brakeman/checks/check_filter_skipping.rb
152
179
  - lib/brakeman/checks/check_mail_to.rb
@@ -168,28 +195,37 @@ files:
168
195
  - lib/brakeman/processor.rb
169
196
  - lib/brakeman.rb
170
197
  - lib/brakeman/format/style.css
198
+ has_rdoc: true
171
199
  homepage: http://brakemanscanner.org
172
200
  licenses: []
201
+
173
202
  post_install_message:
174
203
  rdoc_options: []
175
- require_paths:
204
+
205
+ require_paths:
176
206
  - lib
177
- required_ruby_version: !ruby/object:Gem::Requirement
207
+ required_ruby_version: !ruby/object:Gem::Requirement
178
208
  none: false
179
- requirements:
180
- - - ! '>='
181
- - !ruby/object:Gem::Version
182
- version: '0'
183
- required_rubygems_version: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - ">="
211
+ - !ruby/object:Gem::Version
212
+ segments:
213
+ - 0
214
+ version: "0"
215
+ required_rubygems_version: !ruby/object:Gem::Requirement
184
216
  none: false
185
- requirements:
186
- - - ! '>='
187
- - !ruby/object:Gem::Version
188
- version: '0'
217
+ requirements:
218
+ - - ">="
219
+ - !ruby/object:Gem::Version
220
+ segments:
221
+ - 0
222
+ version: "0"
189
223
  requirements: []
224
+
190
225
  rubyforge_project:
191
- rubygems_version: 1.8.10
226
+ rubygems_version: 1.3.7
192
227
  signing_key:
193
228
  specification_version: 3
194
229
  summary: Security vulnerability scanner for Ruby on Rails.
195
230
  test_files: []
231
+