brakeman 1.8.0 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|