brakeman 3.1.0 → 3.1.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.
- checksums.yaml +4 -4
- data/CHANGES +14 -0
- data/lib/brakeman/call_index.rb +14 -1
- data/lib/brakeman/checks/check_link_to_href.rb +9 -0
- data/lib/brakeman/checks/check_session_manipulation.rb +36 -0
- data/lib/brakeman/checks/check_sql.rb +3 -1
- data/lib/brakeman/checks/check_weak_hash.rb +152 -0
- data/lib/brakeman/processors/alias_processor.rb +26 -9
- data/lib/brakeman/processors/haml_template_processor.rb +41 -19
- data/lib/brakeman/processors/lib/processor_helper.rb +0 -28
- data/lib/brakeman/util.rb +36 -3
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning_codes.rb +3 -0
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7a5cc8e49df767622714791bc13b5d32717b23e9
|
|
4
|
+
data.tar.gz: 433d3fccd753f8f51795e34b2a7d1b6e54387023
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 07264b78f6664f20e8a989998b1bac98d2235ab5324d69ba490ca0a49cafd7acf5f999f2a472eaa026a6dc0879059955302a08cb03338f5967acf13a6deebe5d
|
|
7
|
+
data.tar.gz: 0c591fe4bc92ec53608dd11dd62592f1ab3f37de5b65c8d76020f6412c19ff816d5f526a74ef4bfe4edabd197c39ababb8824739127c1b1f39db3a4c3a0d359b
|
data/CHANGES
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# 3.1.1
|
|
2
|
+
|
|
3
|
+
* Add optional check for use of MD5 and SHA1
|
|
4
|
+
* Avoid warning when linking to decorated models
|
|
5
|
+
* Add check for user input in session keys
|
|
6
|
+
* Fix chained assignment
|
|
7
|
+
* Treat a.try(&:b) like a.b()
|
|
8
|
+
* Consider j/escape_javascript safe inside HAML JavaScript blocks
|
|
9
|
+
* Better HAML processing of find_and_preserve calls
|
|
10
|
+
* Add more Arel methods to be ignored in SQL
|
|
11
|
+
* Fix absolute paths for Windows (Cody Frederick)
|
|
12
|
+
* Support newer terminal-table releases
|
|
13
|
+
* Allow searching call index methods by regex (Alex Ianus)
|
|
14
|
+
|
|
1
15
|
# 3.1.0
|
|
2
16
|
|
|
3
17
|
* Add support for gems.rb/gems.locked
|
data/lib/brakeman/call_index.rb
CHANGED
|
@@ -98,9 +98,12 @@ class Brakeman::CallIndex
|
|
|
98
98
|
@calls_by_method[call[:method]] ||= []
|
|
99
99
|
@calls_by_method[call[:method]] << call
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
if not call[:target].is_a? Sexp
|
|
102
102
|
@calls_by_target[call[:target]] ||= []
|
|
103
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
|
|
104
107
|
end
|
|
105
108
|
end
|
|
106
109
|
end
|
|
@@ -139,6 +142,8 @@ class Brakeman::CallIndex
|
|
|
139
142
|
def calls_by_method method
|
|
140
143
|
if method.is_a? Array
|
|
141
144
|
calls_by_methods method
|
|
145
|
+
elsif method.is_a? Regexp
|
|
146
|
+
calls_by_methods_regex method
|
|
142
147
|
else
|
|
143
148
|
@calls_by_method[method.to_sym] || []
|
|
144
149
|
end
|
|
@@ -155,6 +160,14 @@ class Brakeman::CallIndex
|
|
|
155
160
|
calls
|
|
156
161
|
end
|
|
157
162
|
|
|
163
|
+
def calls_by_methods_regex methods_regex
|
|
164
|
+
calls = []
|
|
165
|
+
@calls_by_method.each do |key, value|
|
|
166
|
+
calls.concat value if key.to_s.match methods_regex
|
|
167
|
+
end
|
|
168
|
+
calls
|
|
169
|
+
end
|
|
170
|
+
|
|
158
171
|
def calls_with_no_target
|
|
159
172
|
@calls_by_target[nil] || []
|
|
160
173
|
end
|
|
@@ -91,6 +91,15 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
def ignore_call? target, method
|
|
95
|
+
decorated_model? method or super
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def decorated_model? method
|
|
99
|
+
tracker.config.has_gem? :draper and
|
|
100
|
+
method == :decorate
|
|
101
|
+
end
|
|
102
|
+
|
|
94
103
|
def ignored_method? target, method
|
|
95
104
|
@ignore_methods.include? method or
|
|
96
105
|
method.to_s =~ /_path$/ or
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
class Brakeman::CheckSessionManipulation < Brakeman::BaseCheck
|
|
4
|
+
Brakeman::Checks.add self
|
|
5
|
+
|
|
6
|
+
@description = "Check for user input in session keys"
|
|
7
|
+
|
|
8
|
+
def run_check
|
|
9
|
+
tracker.find_call(:method => :[]=, :target => :session).each do |result|
|
|
10
|
+
process_result result
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def process_result result
|
|
15
|
+
return if duplicate? result or result[:call].original_line
|
|
16
|
+
add_result result
|
|
17
|
+
|
|
18
|
+
index = result[:call].first_arg
|
|
19
|
+
|
|
20
|
+
if input = has_immediate_user_input?(index)
|
|
21
|
+
if params? index
|
|
22
|
+
confidence = CONFIDENCE[:high]
|
|
23
|
+
else
|
|
24
|
+
confidence = CONFIDENCE[:med]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
warn :result => result,
|
|
28
|
+
:warning_type => "Session Manipulation",
|
|
29
|
+
:warning_code => :session_key_manipulation,
|
|
30
|
+
:message => "#{friendly_type_of(input).capitalize} used as key in session hash",
|
|
31
|
+
:code => result[:call],
|
|
32
|
+
:user_input => input.match,
|
|
33
|
+
:confidence => confidence
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -585,7 +585,9 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
585
585
|
end
|
|
586
586
|
end
|
|
587
587
|
|
|
588
|
-
AREL_METHODS = [:
|
|
588
|
+
AREL_METHODS = [:all, :and, :arel_table, :as, :eq, :eq_any, :exists, :group,
|
|
589
|
+
:gt, :gteq, :having, :in, :join_sources, :limit, :lt, :lteq, :not,
|
|
590
|
+
:not_eq, :on, :or, :order, :project, :skip, :take, :where, :with]
|
|
589
591
|
|
|
590
592
|
def arel? exp
|
|
591
593
|
call? exp and (AREL_METHODS.include? exp.method or arel? exp.target)
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
class Brakeman::CheckWeakHash < Brakeman::BaseCheck
|
|
4
|
+
Brakeman::Checks.add_optional self
|
|
5
|
+
|
|
6
|
+
@description = "Checks for use of weak hashes like MD5"
|
|
7
|
+
|
|
8
|
+
DIGEST_CALLS = [:base64digest, :digest, :hexdigest, :new]
|
|
9
|
+
|
|
10
|
+
def run_check
|
|
11
|
+
tracker.find_call(:targets => [:'Digest::MD5', :'Digest::SHA1', :'OpenSSL::Digest::MD5', :'OpenSSL::Digest::SHA1'], :nested => true).each do |result|
|
|
12
|
+
process_hash_result result
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
tracker.find_call(:target => :'Digest::HMAC', :methods => [:new, :hexdigest], :nested => true).each do |result|
|
|
16
|
+
process_hmac_result result
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
tracker.find_call(:targets => [:'OpenSSL::Digest::Digest', :'OpenSSL::Digest'], :method => :new).each do |result|
|
|
20
|
+
process_openssl_result result
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def process_hash_result result
|
|
25
|
+
return if duplicate? result
|
|
26
|
+
add_result result
|
|
27
|
+
|
|
28
|
+
input = nil
|
|
29
|
+
call = result[:call]
|
|
30
|
+
|
|
31
|
+
if DIGEST_CALLS.include? call.method
|
|
32
|
+
if input = user_input_as_arg?(call)
|
|
33
|
+
input = input.match
|
|
34
|
+
confidence = CONFIDENCE[:high]
|
|
35
|
+
elsif input = hashing_password?(call)
|
|
36
|
+
confidence = CONFIDENCE[:high]
|
|
37
|
+
else
|
|
38
|
+
confidence = CONFIDENCE[:med]
|
|
39
|
+
end
|
|
40
|
+
else
|
|
41
|
+
confidence = CONFIDENCE[:med]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
alg = case call.target.last
|
|
46
|
+
when :MD5
|
|
47
|
+
" (MD5)"
|
|
48
|
+
when :SHA1
|
|
49
|
+
" (SHA1)"
|
|
50
|
+
else
|
|
51
|
+
""
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
warn :result => result,
|
|
55
|
+
:warning_type => "Weak Hash",
|
|
56
|
+
:warning_code => :weak_hash_digest,
|
|
57
|
+
:message => "Weak hashing algorithm#{alg} used",
|
|
58
|
+
:confidence => confidence,
|
|
59
|
+
:user_input => input
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def process_hmac_result result
|
|
63
|
+
return if duplicate? result
|
|
64
|
+
add_result result
|
|
65
|
+
|
|
66
|
+
call = result[:call]
|
|
67
|
+
|
|
68
|
+
alg = case call.third_arg.last
|
|
69
|
+
when :MD5
|
|
70
|
+
'MD5'
|
|
71
|
+
when :SHA1
|
|
72
|
+
'SHA1'
|
|
73
|
+
else
|
|
74
|
+
return
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
warn :result => result,
|
|
78
|
+
:warning_type => "Weak Hash",
|
|
79
|
+
:warning_code => :weak_hash_hmac,
|
|
80
|
+
:message => "Weak hashing algorithm (#{alg}) used in HMAC",
|
|
81
|
+
:confidence => CONFIDENCE[:med]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def process_openssl_result result
|
|
85
|
+
return if duplicate? result
|
|
86
|
+
add_result result
|
|
87
|
+
|
|
88
|
+
arg = result[:call].first_arg
|
|
89
|
+
|
|
90
|
+
if string? arg
|
|
91
|
+
alg = arg.value.upcase
|
|
92
|
+
|
|
93
|
+
if alg == 'MD5' or alg == 'SHA1'
|
|
94
|
+
warn :result => result,
|
|
95
|
+
:warning_type => "Weak Hash",
|
|
96
|
+
:warning_code => :weak_hash_digest,
|
|
97
|
+
:message => "Weak hashing algorithm (#{alg}) used",
|
|
98
|
+
:confidence => CONFIDENCE[:med]
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def user_input_as_arg? call
|
|
104
|
+
call.each_arg do |arg|
|
|
105
|
+
if input = include_user_input?(arg)
|
|
106
|
+
return input
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def hashing_password? call
|
|
114
|
+
call.each_arg do |arg|
|
|
115
|
+
@has_password = false
|
|
116
|
+
|
|
117
|
+
process arg
|
|
118
|
+
|
|
119
|
+
if @has_password
|
|
120
|
+
return @has_password
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
nil
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def process_call exp
|
|
128
|
+
if exp.method == :password
|
|
129
|
+
@has_password = exp
|
|
130
|
+
else
|
|
131
|
+
process_default exp
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
exp
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def process_ivar exp
|
|
138
|
+
if exp.value == :@password
|
|
139
|
+
@has_password = exp
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
exp
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def process_lvar exp
|
|
146
|
+
if exp.value == :password
|
|
147
|
+
@has_password = exp
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
exp
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -274,6 +274,15 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
274
274
|
exp
|
|
275
275
|
end
|
|
276
276
|
|
|
277
|
+
# Handles x = y = z = 1
|
|
278
|
+
def get_rhs exp
|
|
279
|
+
if node_type? exp, :lasgn, :iasgn, :gasgn, :attrasgn, :cvdecl, :cdecl
|
|
280
|
+
get_rhs(exp.rhs)
|
|
281
|
+
else
|
|
282
|
+
exp
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
277
286
|
#Local assignment
|
|
278
287
|
# x = 1
|
|
279
288
|
def process_lasgn exp
|
|
@@ -285,9 +294,9 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
285
294
|
|
|
286
295
|
if self_assign
|
|
287
296
|
# Skip branching
|
|
288
|
-
env[local] = exp
|
|
297
|
+
env[local] = get_rhs(exp)
|
|
289
298
|
else
|
|
290
|
-
set_value local, exp
|
|
299
|
+
set_value local, get_rhs(exp)
|
|
291
300
|
end
|
|
292
301
|
|
|
293
302
|
exp
|
|
@@ -302,12 +311,12 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
302
311
|
|
|
303
312
|
if self_assign
|
|
304
313
|
if env[ivar].nil? and @meth_env
|
|
305
|
-
@meth_env[ivar] = exp
|
|
314
|
+
@meth_env[ivar] = get_rhs(exp)
|
|
306
315
|
else
|
|
307
|
-
env[ivar] = exp
|
|
316
|
+
env[ivar] = get_rhs(exp)
|
|
308
317
|
end
|
|
309
318
|
else
|
|
310
|
-
set_value ivar, exp
|
|
319
|
+
set_value ivar, get_rhs(exp)
|
|
311
320
|
end
|
|
312
321
|
|
|
313
322
|
exp
|
|
@@ -317,7 +326,8 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
317
326
|
# $x = 1
|
|
318
327
|
def process_gasgn exp
|
|
319
328
|
match = Sexp.new(:gvar, exp.lhs)
|
|
320
|
-
|
|
329
|
+
exp.rhs = process(exp.rhs)
|
|
330
|
+
value = get_rhs(exp)
|
|
321
331
|
value.line = exp.line
|
|
322
332
|
|
|
323
333
|
set_value match, value
|
|
@@ -329,7 +339,8 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
329
339
|
# @@x = 1
|
|
330
340
|
def process_cvdecl exp
|
|
331
341
|
match = Sexp.new(:cvar, exp.lhs)
|
|
332
|
-
|
|
342
|
+
exp.rhs = process(exp.rhs)
|
|
343
|
+
value = get_rhs(exp)
|
|
333
344
|
|
|
334
345
|
set_value match, value
|
|
335
346
|
|
|
@@ -358,7 +369,8 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
358
369
|
env[tar_variable] = hash_insert target.deep_clone, index, value
|
|
359
370
|
end
|
|
360
371
|
elsif method.to_s[-1,1] == "="
|
|
361
|
-
|
|
372
|
+
exp.first_arg = process(index_arg)
|
|
373
|
+
value = get_rhs(exp)
|
|
362
374
|
#This is what we'll replace with the value
|
|
363
375
|
match = Sexp.new(:call, target, method.to_s[0..-2].to_sym)
|
|
364
376
|
|
|
@@ -478,7 +490,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
478
490
|
match = exp.lhs
|
|
479
491
|
end
|
|
480
492
|
|
|
481
|
-
env[match] = exp
|
|
493
|
+
env[match] = get_rhs(exp)
|
|
482
494
|
|
|
483
495
|
exp
|
|
484
496
|
end
|
|
@@ -634,6 +646,11 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
634
646
|
|
|
635
647
|
# Change x.send(:y, 1) to x.y(1)
|
|
636
648
|
def collapse_send_call exp, first_arg
|
|
649
|
+
# Handle try(&:id)
|
|
650
|
+
if node_type? first_arg, :block_pass
|
|
651
|
+
first_arg = first_arg[1]
|
|
652
|
+
end
|
|
653
|
+
|
|
637
654
|
return unless symbol? first_arg or string? first_arg
|
|
638
655
|
exp.method = first_arg.value.to_sym
|
|
639
656
|
args = exp.args
|
|
@@ -4,7 +4,8 @@ require 'brakeman/processors/template_processor'
|
|
|
4
4
|
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
|
+
|
|
8
9
|
#Processes call, looking for template output
|
|
9
10
|
def process_call exp
|
|
10
11
|
target = exp.target
|
|
@@ -36,20 +37,31 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
|
36
37
|
if string? out
|
|
37
38
|
ignore
|
|
38
39
|
else
|
|
39
|
-
case method.to_s
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
r = case method.to_s
|
|
41
|
+
when "push_text"
|
|
42
|
+
build_output_from_push_text(out)
|
|
43
|
+
when HAML_FORMAT_METHOD
|
|
44
|
+
if $4 == "true"
|
|
45
|
+
if string_interp? out
|
|
46
|
+
build_output_from_push_text(out, :escaped_output)
|
|
47
|
+
else
|
|
48
|
+
Sexp.new :format_escaped, out
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
if string_interp? out
|
|
52
|
+
build_output_from_push_text(out)
|
|
53
|
+
else
|
|
54
|
+
Sexp.new :format, out
|
|
55
|
+
end
|
|
56
|
+
end
|
|
52
57
|
|
|
58
|
+
else
|
|
59
|
+
raise "Unrecognized action on _hamlout: #{method}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
@javascript = false
|
|
63
|
+
r
|
|
64
|
+
end
|
|
53
65
|
end
|
|
54
66
|
|
|
55
67
|
res.line(exp.line)
|
|
@@ -75,6 +87,14 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
|
75
87
|
#Process call to render()
|
|
76
88
|
exp.arglist = process exp.arglist
|
|
77
89
|
make_render_in_view exp
|
|
90
|
+
elsif target == nil and method == :find_and_preserve
|
|
91
|
+
process exp.first_arg
|
|
92
|
+
elsif method == :render_with_options
|
|
93
|
+
if target == JAVASCRIPT_FILTER
|
|
94
|
+
@javascript = true
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
process exp.first_arg
|
|
78
98
|
else
|
|
79
99
|
exp.target = target
|
|
80
100
|
exp.arglist = process exp.arglist
|
|
@@ -117,7 +137,7 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
|
117
137
|
|
|
118
138
|
#HAML likes to put interpolated values into _hamlout.push_text
|
|
119
139
|
#but we want to handle those individually
|
|
120
|
-
def build_output_from_push_text exp
|
|
140
|
+
def build_output_from_push_text exp, default = :output
|
|
121
141
|
if string_interp? exp
|
|
122
142
|
exp.map! do |e|
|
|
123
143
|
if sexp? e
|
|
@@ -125,7 +145,7 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
|
125
145
|
e = e.value
|
|
126
146
|
end
|
|
127
147
|
|
|
128
|
-
get_pushed_value e
|
|
148
|
+
get_pushed_value e, default
|
|
129
149
|
else
|
|
130
150
|
e
|
|
131
151
|
end
|
|
@@ -134,9 +154,9 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
|
134
154
|
end
|
|
135
155
|
|
|
136
156
|
#Gets outputs from values interpolated into _hamlout.push_text
|
|
137
|
-
def get_pushed_value exp
|
|
157
|
+
def get_pushed_value exp, default = :output
|
|
138
158
|
return exp unless sexp? exp
|
|
139
|
-
|
|
159
|
+
|
|
140
160
|
case exp.node_type
|
|
141
161
|
when :format
|
|
142
162
|
exp.node_type = :output
|
|
@@ -153,8 +173,10 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
|
153
173
|
else
|
|
154
174
|
if call? exp and exp.target == HAML_HELPERS and exp.method == :html_escape
|
|
155
175
|
s = Sexp.new(:escaped_output, exp.first_arg)
|
|
176
|
+
elsif @javascript and call? exp and (exp.method == :j or exp.method == :escape_javascript)
|
|
177
|
+
s = Sexp.new(:escaped_output, exp.first_arg)
|
|
156
178
|
else
|
|
157
|
-
s = Sexp.new(
|
|
179
|
+
s = Sexp.new(default, exp)
|
|
158
180
|
end
|
|
159
181
|
|
|
160
182
|
s.line(exp.line)
|
|
@@ -59,32 +59,4 @@ module Brakeman::ProcessorHelper
|
|
|
59
59
|
|
|
60
60
|
exp
|
|
61
61
|
end
|
|
62
|
-
|
|
63
|
-
#Returns a class name as a Symbol.
|
|
64
|
-
#If class name cannot be determined, returns _exp_.
|
|
65
|
-
def class_name exp
|
|
66
|
-
case exp
|
|
67
|
-
when Sexp
|
|
68
|
-
case exp.node_type
|
|
69
|
-
when :const
|
|
70
|
-
exp.value
|
|
71
|
-
when :lvar
|
|
72
|
-
exp.value.to_sym
|
|
73
|
-
when :colon2
|
|
74
|
-
"#{class_name(exp.lhs)}::#{exp.rhs}".to_sym
|
|
75
|
-
when :colon3
|
|
76
|
-
"::#{exp.value}".to_sym
|
|
77
|
-
when :self
|
|
78
|
-
@current_class || @current_module || nil
|
|
79
|
-
else
|
|
80
|
-
exp
|
|
81
|
-
end
|
|
82
|
-
when Symbol
|
|
83
|
-
exp
|
|
84
|
-
when nil
|
|
85
|
-
nil
|
|
86
|
-
else
|
|
87
|
-
exp
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
62
|
end
|
data/lib/brakeman/util.rb
CHANGED
|
@@ -45,6 +45,33 @@ module Brakeman::Util
|
|
|
45
45
|
word + "s"
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
#Returns a class name as a Symbol.
|
|
49
|
+
#If class name cannot be determined, returns _exp_.
|
|
50
|
+
def class_name exp
|
|
51
|
+
case exp
|
|
52
|
+
when Sexp
|
|
53
|
+
case exp.node_type
|
|
54
|
+
when :const
|
|
55
|
+
exp.value
|
|
56
|
+
when :lvar
|
|
57
|
+
exp.value.to_sym
|
|
58
|
+
when :colon2
|
|
59
|
+
"#{class_name(exp.lhs)}::#{exp.rhs}".to_sym
|
|
60
|
+
when :colon3
|
|
61
|
+
"::#{exp.value}".to_sym
|
|
62
|
+
when :self
|
|
63
|
+
@current_class || @current_module || nil
|
|
64
|
+
else
|
|
65
|
+
exp
|
|
66
|
+
end
|
|
67
|
+
when Symbol
|
|
68
|
+
exp
|
|
69
|
+
when nil
|
|
70
|
+
nil
|
|
71
|
+
else
|
|
72
|
+
exp
|
|
73
|
+
end
|
|
74
|
+
end
|
|
48
75
|
|
|
49
76
|
#Takes an Sexp like
|
|
50
77
|
# (:hash, (:lit, :key), (:str, "value"))
|
|
@@ -384,8 +411,9 @@ module Brakeman::Util
|
|
|
384
411
|
end
|
|
385
412
|
|
|
386
413
|
def relative_path file
|
|
387
|
-
|
|
388
|
-
|
|
414
|
+
pname = Pathname.new file
|
|
415
|
+
if file and not file.empty? and pname.absolute?
|
|
416
|
+
pname.relative_path_from(Pathname.new(@tracker.app_path)).to_s
|
|
389
417
|
else
|
|
390
418
|
file
|
|
391
419
|
end
|
|
@@ -434,7 +462,12 @@ module Brakeman::Util
|
|
|
434
462
|
return "" unless table
|
|
435
463
|
|
|
436
464
|
Brakeman.load_brakeman_dependency 'terminal-table'
|
|
437
|
-
|
|
465
|
+
headings = table.headings
|
|
466
|
+
if headings.is_a? Array
|
|
467
|
+
headings = headings.first
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
output = CSV.generate_line(headings.cells.map{|cell| cell.to_s.strip})
|
|
438
471
|
table.rows.each do |row|
|
|
439
472
|
output << CSV.generate_line(row.cells.map{|cell| cell.to_s.strip})
|
|
440
473
|
end
|
data/lib/brakeman/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brakeman
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.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: 2015-
|
|
12
|
+
date: 2015-09-23 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: test-unit
|
|
@@ -65,14 +65,14 @@ dependencies:
|
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: 1.4
|
|
68
|
+
version: '1.4'
|
|
69
69
|
type: :runtime
|
|
70
70
|
prerelease: false
|
|
71
71
|
version_requirements: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: 1.4
|
|
75
|
+
version: '1.4'
|
|
76
76
|
- !ruby/object:Gem::Dependency
|
|
77
77
|
name: fastercsv
|
|
78
78
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -244,6 +244,7 @@ files:
|
|
|
244
244
|
- lib/brakeman/checks/check_select_vulnerability.rb
|
|
245
245
|
- lib/brakeman/checks/check_send.rb
|
|
246
246
|
- lib/brakeman/checks/check_send_file.rb
|
|
247
|
+
- lib/brakeman/checks/check_session_manipulation.rb
|
|
247
248
|
- lib/brakeman/checks/check_session_settings.rb
|
|
248
249
|
- lib/brakeman/checks/check_simple_format.rb
|
|
249
250
|
- lib/brakeman/checks/check_single_quotes.rb
|
|
@@ -258,6 +259,7 @@ files:
|
|
|
258
259
|
- lib/brakeman/checks/check_unsafe_reflection.rb
|
|
259
260
|
- lib/brakeman/checks/check_unscoped_find.rb
|
|
260
261
|
- lib/brakeman/checks/check_validation_regex.rb
|
|
262
|
+
- lib/brakeman/checks/check_weak_hash.rb
|
|
261
263
|
- lib/brakeman/checks/check_without_protection.rb
|
|
262
264
|
- lib/brakeman/checks/check_xml_dos.rb
|
|
263
265
|
- lib/brakeman/checks/check_yaml_parsing.rb
|