brakeman 1.8.0 → 1.8.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/lib/brakeman.rb +1 -1
- data/lib/brakeman/checks/base_check.rb +4 -4
- data/lib/brakeman/checks/check_mail_to.rb +5 -7
- data/lib/brakeman/checks/check_redirect.rb +4 -0
- data/lib/brakeman/checks/check_select_vulnerability.rb +1 -1
- data/lib/brakeman/checks/check_sql.rb +2 -2
- data/lib/brakeman/processors/alias_processor.rb +3 -3
- data/lib/brakeman/processors/haml_template_processor.rb +5 -6
- data/lib/brakeman/processors/output_processor.rb +1 -31
- data/lib/brakeman/rescanner.rb +2 -2
- data/lib/brakeman/version.rb +1 -1
- data/lib/ruby_parser/bm_sexp.rb +57 -15
- metadata +4 -4
data/lib/brakeman.rb
CHANGED
|
@@ -428,17 +428,17 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
|
428
428
|
high_version = high_version.split(".").map! { |n| n.to_i }
|
|
429
429
|
|
|
430
430
|
version.each_with_index do |v, i|
|
|
431
|
-
if v < low_version
|
|
431
|
+
if v < low_version.fetch(i, 0)
|
|
432
432
|
return false
|
|
433
|
-
elsif v > low_version
|
|
433
|
+
elsif v > low_version.fetch(i, 0)
|
|
434
434
|
break
|
|
435
435
|
end
|
|
436
436
|
end
|
|
437
437
|
|
|
438
438
|
version.each_with_index do |v, i|
|
|
439
|
-
if v > high_version
|
|
439
|
+
if v > high_version.fetch(i, 0)
|
|
440
440
|
return false
|
|
441
|
-
elsif v < high_version
|
|
441
|
+
elsif v < high_version.fetch(i, 0)
|
|
442
442
|
break
|
|
443
443
|
end
|
|
444
444
|
end
|
|
@@ -23,7 +23,8 @@ class Brakeman::CheckMailTo < Brakeman::BaseCheck
|
|
|
23
23
|
:warning_type => "Mail Link",
|
|
24
24
|
:message => message,
|
|
25
25
|
:confidence => CONFIDENCE[:high],
|
|
26
|
-
:file => gemfile_or_environment
|
|
26
|
+
:file => gemfile_or_environment,
|
|
27
|
+
:link_path => "https://groups.google.com/d/topic/rubyonrails-security/8CpI7egxX4E/discussion"
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
30
|
|
|
@@ -33,13 +34,10 @@ class Brakeman::CheckMailTo < Brakeman::BaseCheck
|
|
|
33
34
|
Brakeman.debug "Checking calls to mail_to for javascript encoding"
|
|
34
35
|
|
|
35
36
|
tracker.find_call(:target => false, :method => :mail_to).each do |result|
|
|
36
|
-
|
|
37
|
-
args = call.args
|
|
38
|
-
|
|
39
|
-
args.each do |arg|
|
|
37
|
+
result[:call].arglist.each do |arg|
|
|
40
38
|
if hash? arg
|
|
41
|
-
if hash_access(arg, :
|
|
42
|
-
return result
|
|
39
|
+
if option = hash_access(arg, :encode)
|
|
40
|
+
return result if symbol? option and option.value == :javascript
|
|
43
41
|
end
|
|
44
42
|
end
|
|
45
43
|
end
|
|
@@ -59,6 +59,10 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
|
59
59
|
args = call.args
|
|
60
60
|
first_arg = call.first_arg
|
|
61
61
|
|
|
62
|
+
# if the first argument is an array, rails assumes you are building a
|
|
63
|
+
# polymorphic route, which will never jump off-host
|
|
64
|
+
return false if array? first_arg
|
|
65
|
+
|
|
62
66
|
if tracker.options[:ignore_redirect_to_model] and call? first_arg and
|
|
63
67
|
(@model_find_calls.include? first_arg.method or first_arg.method.to_s.match(/^find_by_/)) and
|
|
64
68
|
model_name? first_arg.target
|
|
@@ -15,7 +15,7 @@ class Brakeman::CheckSelectVulnerability < Brakeman::BaseCheck
|
|
|
15
15
|
suggested_version = "3.1.4"
|
|
16
16
|
elsif version_between? "3.2.0", "3.2.1"
|
|
17
17
|
suggested_version = "3.2.2"
|
|
18
|
-
elsif version_between? "2.0.0", "3.
|
|
18
|
+
elsif version_between? "2.0.0", "2.3.14"
|
|
19
19
|
suggested_version = "3 or use options_for_select"
|
|
20
20
|
else
|
|
21
21
|
return
|
|
@@ -90,7 +90,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
def check_rails_version_for_cve_2012_2660
|
|
93
|
-
if version_between?("2.0.0", "3.
|
|
93
|
+
if version_between?("2.0.0", "2.3.14") || version_between?("3.0.0", "3.0.12") || version_between?("3.1.0", "3.1.4") || version_between?("3.2.0", "3.2.3")
|
|
94
94
|
warn :warning_type => 'SQL Injection',
|
|
95
95
|
:message => 'All versions of Rails before 3.0.13, 3.1.5, and 3.2.5 contain a SQL Query Generation Vulnerability: CVE-2012-2660; Upgrade to 3.2.5, 3.1.5, 3.0.13',
|
|
96
96
|
:confidence => CONFIDENCE[:high],
|
|
@@ -110,7 +110,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
def check_rails_version_for_cve_2012_2695
|
|
113
|
-
if version_between?("2.0.0", "3.
|
|
113
|
+
if version_between?("2.0.0", "2.3.14") || version_between?("3.0.0", "3.0.13") || version_between?("3.1.0", "3.1.5") || version_between?("3.2.0", "3.2.5")
|
|
114
114
|
warn :warning_type => 'SQL Injection',
|
|
115
115
|
:message => 'All versions of Rails before 3.0.14, 3.1.6, and 3.2.6 contain SQL Injection Vulnerabilities: CVE-2012-2694 and CVE-2012-2695; Upgrade to 3.2.6, 3.1.6, 3.0.14',
|
|
116
116
|
:confidence => CONFIDENCE[:high],
|
|
@@ -450,11 +450,11 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
450
450
|
#
|
|
451
451
|
#Returns the value inside the array, if possible.
|
|
452
452
|
def process_array_access target, args
|
|
453
|
-
if args.length == 1 and integer? args
|
|
454
|
-
index = args
|
|
453
|
+
if args.length == 1 and integer? args.first
|
|
454
|
+
index = args.first.value
|
|
455
455
|
|
|
456
456
|
#Have to do this because first element is :array and we have to skip it
|
|
457
|
-
target[1..-1][index
|
|
457
|
+
target[1..-1][index]
|
|
458
458
|
else
|
|
459
459
|
nil
|
|
460
460
|
end
|
|
@@ -29,16 +29,15 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
|
29
29
|
|
|
30
30
|
method = exp.method
|
|
31
31
|
|
|
32
|
-
if (call? target and target.method == :_hamlout)
|
|
32
|
+
if (call? target and target.method == :_hamlout)
|
|
33
33
|
res = case method
|
|
34
34
|
when :adjust_tabs, :rstrip!, :attributes #Check attributes, maybe?
|
|
35
35
|
ignore
|
|
36
|
-
when :options
|
|
37
|
-
|
|
38
|
-
when :buffer
|
|
39
|
-
Sexp.new :call, :_hamlout, :buffer, exp.arglist
|
|
36
|
+
when :options, :buffer
|
|
37
|
+
exp
|
|
40
38
|
when :open_tag
|
|
41
|
-
|
|
39
|
+
process(exp.arglist)
|
|
40
|
+
exp
|
|
42
41
|
else
|
|
43
42
|
arg = exp.first_arg
|
|
44
43
|
|
|
@@ -10,7 +10,7 @@ class Brakeman::OutputProcessor < Ruby2Ruby
|
|
|
10
10
|
|
|
11
11
|
#Copies +exp+ and then formats it.
|
|
12
12
|
def format exp
|
|
13
|
-
process
|
|
13
|
+
process(exp.deep_clone) || "[Format Error]"
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
alias process_safely format
|
|
@@ -23,36 +23,6 @@ class Brakeman::OutputProcessor < Ruby2Ruby
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def process_call exp
|
|
27
|
-
if exp[0].is_a? Symbol
|
|
28
|
-
target = exp[0]
|
|
29
|
-
|
|
30
|
-
method = exp[1]
|
|
31
|
-
|
|
32
|
-
args = process exp[2]
|
|
33
|
-
|
|
34
|
-
out = nil
|
|
35
|
-
|
|
36
|
-
if method == :[]
|
|
37
|
-
if target
|
|
38
|
-
out = "#{target}[#{args}]"
|
|
39
|
-
else
|
|
40
|
-
raise Exception.new("Not sure what to do with access and no target: #{exp}")
|
|
41
|
-
end
|
|
42
|
-
else
|
|
43
|
-
if target
|
|
44
|
-
out = "#{target}.#{method}(#{args})"
|
|
45
|
-
else
|
|
46
|
-
out = "#{method}(#{args})"
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
exp.clear
|
|
50
|
-
out
|
|
51
|
-
else
|
|
52
|
-
super exp
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
26
|
def process_lvar exp
|
|
57
27
|
out = "(local #{exp[0]})"
|
|
58
28
|
exp.clear
|
data/lib/brakeman/rescanner.rb
CHANGED
|
@@ -117,7 +117,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
|
|
|
117
117
|
if controller[:file] == path
|
|
118
118
|
tracker.templates.keys.each do |template_name|
|
|
119
119
|
if template_name.to_s.match /(.+)\.#{name}#/
|
|
120
|
-
tracker.
|
|
120
|
+
tracker.reset_template template_name
|
|
121
121
|
end
|
|
122
122
|
end
|
|
123
123
|
|
|
@@ -222,7 +222,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
|
|
|
222
222
|
#Remove templates rendered from this controller
|
|
223
223
|
tracker.templates.keys.each do |template_name|
|
|
224
224
|
if template_name.to_s.match template_matcher
|
|
225
|
-
tracker.
|
|
225
|
+
tracker.reset_template template_name
|
|
226
226
|
end
|
|
227
227
|
end
|
|
228
228
|
|
data/lib/brakeman/version.rb
CHANGED
data/lib/ruby_parser/bm_sexp.rb
CHANGED
|
@@ -35,12 +35,26 @@ class Sexp
|
|
|
35
35
|
self[0] = type
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
#Don't use this, please.
|
|
39
|
+
#:nodoc:
|
|
38
40
|
def resbody delete = false
|
|
39
|
-
#RubyParser
|
|
40
|
-
#method_missing, here's a real method.
|
|
41
|
+
#RubyParser and Ruby2Ruby rely on method_missing for this, but since we
|
|
42
|
+
#don't want to use method_missing, here's a real method.
|
|
41
43
|
find_node :resbody, delete
|
|
42
44
|
end
|
|
43
45
|
|
|
46
|
+
#Don't use this, please.
|
|
47
|
+
#:nodoc:
|
|
48
|
+
def lasgn delete = false
|
|
49
|
+
find_node :lasgn, delete
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#Don't use this, please.
|
|
53
|
+
#:nodoc:
|
|
54
|
+
def iasgn delete = false
|
|
55
|
+
find_node :iasgn, delete
|
|
56
|
+
end
|
|
57
|
+
|
|
44
58
|
alias :node_type :sexp_type
|
|
45
59
|
alias :values :sexp_body # TODO: retire
|
|
46
60
|
|
|
@@ -147,8 +161,14 @@ class Sexp
|
|
|
147
161
|
#s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1)))
|
|
148
162
|
# ^- method
|
|
149
163
|
def method
|
|
150
|
-
expect :call, :attrasgn
|
|
151
|
-
|
|
164
|
+
expect :call, :attrasgn, :super, :zsuper
|
|
165
|
+
|
|
166
|
+
case self.node_type
|
|
167
|
+
when :call, :attrasgn
|
|
168
|
+
self[2]
|
|
169
|
+
when :super, :zsuper
|
|
170
|
+
:super
|
|
171
|
+
end
|
|
152
172
|
end
|
|
153
173
|
|
|
154
174
|
#Sets the arglist in a method call.
|
|
@@ -165,8 +185,18 @@ class Sexp
|
|
|
165
185
|
# s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1), s(:lit, 2)))
|
|
166
186
|
# ^------------ arglist ------------^
|
|
167
187
|
def arglist
|
|
168
|
-
expect :call, :attrasgn
|
|
169
|
-
|
|
188
|
+
expect :call, :attrasgn, :super, :zsuper
|
|
189
|
+
|
|
190
|
+
case self.node_type
|
|
191
|
+
when :call, :attrasgn
|
|
192
|
+
self[3]
|
|
193
|
+
when :super, :zsuper
|
|
194
|
+
if self[1]
|
|
195
|
+
Sexp.new(:arglist).concat self[1..-1]
|
|
196
|
+
else
|
|
197
|
+
Sexp.new(:arglist)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
170
200
|
|
|
171
201
|
#For new ruby_parser
|
|
172
202
|
#Sexp.new(:arglist, *self[3..-1])
|
|
@@ -177,7 +207,7 @@ class Sexp
|
|
|
177
207
|
# s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1), s(:lit, 2)))
|
|
178
208
|
# ^--------args--------^
|
|
179
209
|
def args
|
|
180
|
-
expect :call, :attrasgn
|
|
210
|
+
expect :call, :attrasgn, :super, :zsuper
|
|
181
211
|
#For new ruby_parser
|
|
182
212
|
#if self[3]
|
|
183
213
|
# self[3..-1]
|
|
@@ -185,11 +215,20 @@ class Sexp
|
|
|
185
215
|
# []
|
|
186
216
|
#end
|
|
187
217
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
218
|
+
case self.node_type
|
|
219
|
+
when :call, :attrasgn
|
|
220
|
+
#For old ruby_parser
|
|
221
|
+
if self[3]
|
|
222
|
+
self[3][1..-1]
|
|
223
|
+
else
|
|
224
|
+
[]
|
|
225
|
+
end
|
|
226
|
+
when :super, :zsuper
|
|
227
|
+
if self[1]
|
|
228
|
+
self[1..-1]
|
|
229
|
+
else
|
|
230
|
+
[]
|
|
231
|
+
end
|
|
193
232
|
end
|
|
194
233
|
end
|
|
195
234
|
|
|
@@ -279,13 +318,16 @@ class Sexp
|
|
|
279
318
|
# s(:block, s(:lvar, :y), s(:call, nil, :z, s(:arglist))))
|
|
280
319
|
# ^-------------------- block --------------------------^
|
|
281
320
|
def block
|
|
282
|
-
expect :iter, :call_with_block, :scope
|
|
321
|
+
expect :iter, :call_with_block, :scope, :resbody
|
|
283
322
|
|
|
284
323
|
case self.node_type
|
|
285
324
|
when :iter, :call_with_block
|
|
286
325
|
self[3]
|
|
287
326
|
when :scope
|
|
288
327
|
self[1]
|
|
328
|
+
when :resbody
|
|
329
|
+
#This is for Ruby2Ruby ONLY
|
|
330
|
+
find_node :block
|
|
289
331
|
end
|
|
290
332
|
end
|
|
291
333
|
|
|
@@ -345,7 +387,7 @@ class Sexp
|
|
|
345
387
|
#Sets body
|
|
346
388
|
def body= exp
|
|
347
389
|
expect :defn, :defs, :methdef, :selfdef, :class, :module
|
|
348
|
-
|
|
390
|
+
|
|
349
391
|
case self.node_type
|
|
350
392
|
when :defn, :methdef, :class
|
|
351
393
|
self[3] = exp
|
|
@@ -392,7 +434,7 @@ end
|
|
|
392
434
|
[:[]=, :clear, :collect!, :compact!, :concat, :delete, :delete_at,
|
|
393
435
|
:delete_if, :drop, :drop_while, :fill, :flatten!, :replace, :insert,
|
|
394
436
|
:keep_if, :map!, :pop, :push, :reject!, :replace, :reverse!, :rotate!,
|
|
395
|
-
:select!, :shift, :shuffle!, :slice!, :sort!, :sort_by!, :transpose,
|
|
437
|
+
:select!, :shift, :shuffle!, :slice!, :sort!, :sort_by!, :transpose,
|
|
396
438
|
:uniq!, :unshift].each do |method|
|
|
397
439
|
|
|
398
440
|
Sexp.class_eval <<-RUBY
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brakeman
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 53
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 1
|
|
8
8
|
- 8
|
|
9
|
-
-
|
|
10
|
-
version: 1.8.
|
|
9
|
+
- 1
|
|
10
|
+
version: 1.8.1
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Justin Collins
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2012-09-
|
|
18
|
+
date: 2012-09-24 00:00:00 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
name: activesupport
|