brakeman-lib 3.3.2 → 3.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +13 -0
- data/lib/brakeman/app_tree.rb +6 -1
- data/lib/brakeman/checks/base_check.rb +10 -0
- data/lib/brakeman/checks/check_create_with.rb +1 -2
- data/lib/brakeman/checks/check_cross_site_scripting.rb +0 -4
- data/lib/brakeman/checks/check_deserialize.rb +1 -2
- data/lib/brakeman/checks/check_dynamic_finders.rb +1 -2
- data/lib/brakeman/checks/check_evaluation.rb +1 -2
- data/lib/brakeman/checks/check_execute.rb +2 -5
- data/lib/brakeman/checks/check_file_access.rb +1 -2
- data/lib/brakeman/checks/check_link_to_href.rb +13 -3
- data/lib/brakeman/checks/check_mass_assignment.rb +2 -4
- data/lib/brakeman/checks/check_redirect.rb +1 -4
- data/lib/brakeman/checks/check_regex_dos.rb +1 -2
- data/lib/brakeman/checks/check_render.rb +10 -5
- data/lib/brakeman/checks/check_render_inline.rb +1 -2
- data/lib/brakeman/checks/check_select_tag.rb +1 -2
- data/lib/brakeman/checks/check_send.rb +1 -2
- data/lib/brakeman/checks/check_session_manipulation.rb +1 -2
- data/lib/brakeman/checks/check_simple_format.rb +1 -2
- data/lib/brakeman/checks/check_ssl_verify.rb +1 -2
- data/lib/brakeman/checks/check_symbol_dos.rb +2 -4
- data/lib/brakeman/checks/check_unsafe_reflection.rb +1 -2
- data/lib/brakeman/checks/check_weak_hash.rb +3 -6
- data/lib/brakeman/parsers/template_parser.rb +9 -0
- data/lib/brakeman/processors/base_processor.rb +25 -0
- data/lib/brakeman/processors/controller_processor.rb +6 -99
- data/lib/brakeman/processors/erb_template_processor.rb +1 -4
- data/lib/brakeman/processors/erubis_template_processor.rb +4 -16
- data/lib/brakeman/processors/haml_template_processor.rb +4 -11
- data/lib/brakeman/processors/lib/find_all_calls.rb +13 -25
- data/lib/brakeman/processors/lib/find_return_value.rb +34 -4
- data/lib/brakeman/processors/lib/module_helper.rb +111 -0
- data/lib/brakeman/processors/lib/render_helper.rb +1 -1
- data/lib/brakeman/processors/library_processor.rb +4 -57
- data/lib/brakeman/processors/model_processor.rb +4 -104
- data/lib/brakeman/processors/slim_template_processor.rb +7 -21
- data/lib/brakeman/processors/template_processor.rb +11 -0
- data/lib/brakeman/scanner.rb +1 -1
- data/lib/brakeman/version.rb +1 -1
- data/lib/ruby_parser/bm_sexp.rb +7 -3
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4f086cc0f5c5aa7d689faf4145c49801f21457f
|
4
|
+
data.tar.gz: 6ab7f7fed14040fc66d6973b70147b25cf48f959
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e08d73e3e686eb091e925d425fd16426b10784cffc6bcc67135c296c60e6c02cdcdedde92ba536846dc4d01182d9c8071cc64b8f57c7615e671d8062d5fae901
|
7
|
+
data.tar.gz: b92eed67245b493cfc3bab3f11068bc97983784dea1cc4b0616a0c833d5121015547e513ea9f51fa177693a75ccf0c2180fb1c2d0ec5c78e76dd7646a2fe426d
|
data/CHANGES
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# 3.3.3
|
2
|
+
|
3
|
+
* Show path when no Rails app found (Neil Matatall)
|
4
|
+
* Index calls in view helpers
|
5
|
+
* Process inline template renders
|
6
|
+
* Avoid warning about hashes in link_to hrefs
|
7
|
+
* Add documentation for authentication category
|
8
|
+
* Ignore boolean methods in render paths
|
9
|
+
* Reduce open redirect duplicates
|
10
|
+
* Fix SymbolDoS error with unknown Rails version
|
11
|
+
* Sexp#value returns nil when there is no value
|
12
|
+
* Improve return value estimation
|
13
|
+
|
1
14
|
# 3.3.2
|
2
15
|
|
3
16
|
* Fix serious performance regression with global constant tracking
|
data/lib/brakeman/app_tree.rb
CHANGED
@@ -106,11 +106,16 @@ module Brakeman
|
|
106
106
|
|
107
107
|
def lib_paths
|
108
108
|
@lib_files ||= find_paths("lib").reject { |path| path.include? "/generators/" or path.include? "lib/tasks/" } +
|
109
|
-
find_additional_lib_paths
|
109
|
+
find_additional_lib_paths +
|
110
|
+
find_helper_paths
|
110
111
|
end
|
111
112
|
|
112
113
|
private
|
113
114
|
|
115
|
+
def find_helper_paths
|
116
|
+
find_paths "app/helpers"
|
117
|
+
end
|
118
|
+
|
114
119
|
def find_additional_lib_paths
|
115
120
|
@additional_libs_path.collect{ |path| find_paths path }.flatten
|
116
121
|
end
|
@@ -131,6 +131,10 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
131
131
|
@comparison_ops.include? meth
|
132
132
|
end
|
133
133
|
|
134
|
+
def boolean_method? method
|
135
|
+
method[-1] == "?"
|
136
|
+
end
|
137
|
+
|
134
138
|
#Report a warning
|
135
139
|
def warn options
|
136
140
|
extra_opts = { :check => self.class.to_s }
|
@@ -233,6 +237,12 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
233
237
|
@mass_assign_disabled
|
234
238
|
end
|
235
239
|
|
240
|
+
def original? result
|
241
|
+
return false if result[:call].original_line or duplicate? result
|
242
|
+
add_result result
|
243
|
+
true
|
244
|
+
end
|
245
|
+
|
236
246
|
#This is to avoid reporting duplicates. Checks if the result has been
|
237
247
|
#reported already from the same line number.
|
238
248
|
def duplicate? result, location = nil
|
@@ -30,8 +30,7 @@ class Brakeman::CheckDeserialize < Brakeman::BaseCheck
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def check_deserialize result, target, arg = nil
|
33
|
-
return
|
34
|
-
add_result result
|
33
|
+
return unless original? result
|
35
34
|
|
36
35
|
arg ||= result[:call].first_arg
|
37
36
|
method = result[:call].method
|
@@ -20,8 +20,7 @@ class Brakeman::CheckEvaluation < Brakeman::BaseCheck
|
|
20
20
|
|
21
21
|
#Warns if eval includes user input
|
22
22
|
def process_result result
|
23
|
-
return
|
24
|
-
add_result result
|
23
|
+
return unless original? result
|
25
24
|
|
26
25
|
if input = include_user_input?(result[:call].arglist)
|
27
26
|
warn :result => result,
|
@@ -53,8 +53,7 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
53
53
|
failure = include_user_input?(args) || dangerous_interp?(args)
|
54
54
|
end
|
55
55
|
|
56
|
-
if failure and
|
57
|
-
add_result result
|
56
|
+
if failure and original? result
|
58
57
|
|
59
58
|
if failure.type == :interp #Not from user input
|
60
59
|
confidence = CONFIDENCE[:med]
|
@@ -107,9 +106,7 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
107
106
|
|
108
107
|
#Processes backticks.
|
109
108
|
def process_backticks result
|
110
|
-
return
|
111
|
-
|
112
|
-
add_result result
|
109
|
+
return unless original? result
|
113
110
|
|
114
111
|
exp = result[:call]
|
115
112
|
|
@@ -17,7 +17,7 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
17
17
|
:hidden_field, :hidden_field_tag, :image_tag, :label,
|
18
18
|
:mail_to, :polymorphic_url, :radio_button, :select, :slice,
|
19
19
|
:submit_tag, :text_area, :text_field,
|
20
|
-
:text_field_tag, :url_encode, :u,
|
20
|
+
:text_field_tag, :url_encode, :u,
|
21
21
|
:will_paginate].merge(tracker.options[:url_safe_methods] || [])
|
22
22
|
|
23
23
|
@models = tracker.models.keys
|
@@ -36,6 +36,10 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
36
36
|
@matched = false
|
37
37
|
url_arg = process call.second_arg
|
38
38
|
|
39
|
+
if call? url_arg and url_arg.method == :url_for
|
40
|
+
url_arg = url_arg.first_arg
|
41
|
+
end
|
42
|
+
|
39
43
|
#Ignore situations where the href is an interpolated string
|
40
44
|
#with something before the user input
|
41
45
|
return if string_interp?(url_arg) && !url_arg[1].chomp.empty?
|
@@ -45,7 +49,7 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
45
49
|
if input = has_immediate_user_input?(url_arg)
|
46
50
|
message = "Unsafe #{friendly_type_of input} in link_to href"
|
47
51
|
|
48
|
-
unless duplicate? result
|
52
|
+
unless duplicate? result or call_on_params? url_arg
|
49
53
|
add_result result
|
50
54
|
warn :result => result,
|
51
55
|
:warning_type => "Cross Site Scripting",
|
@@ -74,7 +78,7 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
74
78
|
elsif @matched
|
75
79
|
if @matched.type == :model and not tracker.options[:ignore_model_output]
|
76
80
|
message = "Unsafe model attribute in link_to href"
|
77
|
-
elsif @matched.type == :params
|
81
|
+
elsif @matched.type == :params and not call_on_params? @matched.match
|
78
82
|
message = "Unsafe parameter value in link_to href"
|
79
83
|
end
|
80
84
|
|
@@ -112,4 +116,10 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
112
116
|
MODEL_METHODS.include? exp.method or
|
113
117
|
exp.method.to_s =~ /^find_by_/
|
114
118
|
end
|
119
|
+
|
120
|
+
def call_on_params? exp
|
121
|
+
call? exp and
|
122
|
+
params? exp.target and
|
123
|
+
exp.method != :[]
|
124
|
+
end
|
115
125
|
end
|
@@ -65,8 +65,7 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
65
65
|
|
66
66
|
check = check_call call
|
67
67
|
|
68
|
-
if check and
|
69
|
-
add_result res
|
68
|
+
if check and original? res
|
70
69
|
|
71
70
|
model = tracker.models[res[:chain].first]
|
72
71
|
|
@@ -180,8 +179,7 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
180
179
|
end
|
181
180
|
|
182
181
|
def warn_on_permit! result
|
183
|
-
return
|
184
|
-
add_result result
|
182
|
+
return unless original? result
|
185
183
|
|
186
184
|
confidence = if subsequent_mass_assignment? result
|
187
185
|
CONFIDENCE[:high]
|
@@ -29,10 +29,9 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def process_result result
|
32
|
-
return
|
32
|
+
return unless original? result
|
33
33
|
|
34
34
|
call = result[:call]
|
35
|
-
|
36
35
|
method = call.method
|
37
36
|
|
38
37
|
if method == :redirect_to and
|
@@ -41,8 +40,6 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
41
40
|
not slice_call?(call.first_arg) and
|
42
41
|
res = include_user_input?(call)
|
43
42
|
|
44
|
-
add_result result
|
45
|
-
|
46
43
|
if res.type == :immediate
|
47
44
|
confidence = CONFIDENCE[:high]
|
48
45
|
else
|
@@ -26,8 +26,7 @@ class Brakeman::CheckRegexDoS < Brakeman::BaseCheck
|
|
26
26
|
|
27
27
|
#Warns if regex includes user input
|
28
28
|
def process_result result
|
29
|
-
return
|
30
|
-
add_result result
|
29
|
+
return unless original? result
|
31
30
|
|
32
31
|
call = result[:call]
|
33
32
|
components = call[1..-1]
|
@@ -32,8 +32,7 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
|
|
32
32
|
def check_for_dynamic_path result
|
33
33
|
view = result[:call][2]
|
34
34
|
|
35
|
-
if sexp? view and
|
36
|
-
add_result result
|
35
|
+
if sexp? view and original? result
|
37
36
|
|
38
37
|
if input = has_immediate_user_input?(view)
|
39
38
|
if string_interp? view
|
@@ -84,9 +83,15 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
|
|
84
83
|
end
|
85
84
|
|
86
85
|
def safe_param? exp
|
87
|
-
if params? exp and call? exp
|
88
|
-
|
89
|
-
|
86
|
+
if params? exp and call? exp
|
87
|
+
method_name = exp.method
|
88
|
+
|
89
|
+
if method_name == :[]
|
90
|
+
arg = exp.first_arg
|
91
|
+
symbol? arg and [:controller, :action].include? arg.value
|
92
|
+
else
|
93
|
+
boolean_method? method_name
|
94
|
+
end
|
90
95
|
end
|
91
96
|
end
|
92
97
|
end
|
@@ -34,8 +34,7 @@ class Brakeman::CheckSelectTag < Brakeman::BaseCheck
|
|
34
34
|
|
35
35
|
#Check if select_tag is called with user input in :prompt option
|
36
36
|
def process_result result
|
37
|
-
return
|
38
|
-
add_result result
|
37
|
+
return unless original? result
|
39
38
|
|
40
39
|
#Only concerned if user input is supplied for :prompt option
|
41
40
|
last_arg = result[:call].last_arg
|
@@ -17,8 +17,7 @@ class Brakeman::CheckSend < Brakeman::BaseCheck
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def process_result result
|
20
|
-
return
|
21
|
-
add_result result
|
20
|
+
return unless original? result
|
22
21
|
|
23
22
|
send_call = get_send result[:call]
|
24
23
|
process_call_args send_call
|
@@ -12,8 +12,7 @@ class Brakeman::CheckSessionManipulation < Brakeman::BaseCheck
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def process_result result
|
15
|
-
return
|
16
|
-
add_result result
|
15
|
+
return unless original? result
|
17
16
|
|
18
17
|
index = result[:call].first_arg
|
19
18
|
|
@@ -37,8 +37,7 @@ class Brakeman::CheckSSLVerify < Brakeman::BaseCheck
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def warn_about_ssl_verification_bypass result
|
40
|
-
return
|
41
|
-
add_result result
|
40
|
+
return unless original? result
|
42
41
|
|
43
42
|
warn :result => result,
|
44
43
|
:warning_type => "SSL Verification Bypass",
|
@@ -8,7 +8,7 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
|
|
8
8
|
@description = "Checks for symbol denial of service"
|
9
9
|
|
10
10
|
def run_check
|
11
|
-
return if rails_version > "5.0.0"
|
11
|
+
return if rails_version and rails_version > "5.0.0"
|
12
12
|
|
13
13
|
tracker.find_call(:methods => UNSAFE_METHODS, :nested => true).each do |result|
|
14
14
|
check_unsafe_symbol_creation(result)
|
@@ -16,9 +16,7 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def check_unsafe_symbol_creation result
|
19
|
-
return
|
20
|
-
|
21
|
-
add_result result
|
19
|
+
return unless original? result
|
22
20
|
|
23
21
|
call = result[:call]
|
24
22
|
|
@@ -18,8 +18,7 @@ class Brakeman::CheckUnsafeReflection < Brakeman::BaseCheck
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def check_unsafe_reflection result
|
21
|
-
return
|
22
|
-
add_result result
|
21
|
+
return unless original? result
|
23
22
|
|
24
23
|
call = result[:call]
|
25
24
|
method = call.method
|
@@ -22,8 +22,7 @@ class Brakeman::CheckWeakHash < Brakeman::BaseCheck
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def process_hash_result result
|
25
|
-
return
|
26
|
-
add_result result
|
25
|
+
return unless original? result
|
27
26
|
|
28
27
|
input = nil
|
29
28
|
call = result[:call]
|
@@ -59,8 +58,7 @@ class Brakeman::CheckWeakHash < Brakeman::BaseCheck
|
|
59
58
|
end
|
60
59
|
|
61
60
|
def process_hmac_result result
|
62
|
-
return
|
63
|
-
add_result result
|
61
|
+
return unless original? result
|
64
62
|
|
65
63
|
call = result[:call]
|
66
64
|
|
@@ -81,8 +79,7 @@ class Brakeman::CheckWeakHash < Brakeman::BaseCheck
|
|
81
79
|
end
|
82
80
|
|
83
81
|
def process_openssl_result result
|
84
|
-
return
|
85
|
-
add_result result
|
82
|
+
return unless original? result
|
86
83
|
|
87
84
|
arg = result[:call].first_arg
|
88
85
|
|
@@ -85,5 +85,14 @@ module Brakeman
|
|
85
85
|
Slim::Template.new(:disable_capture => true,
|
86
86
|
:generator => Temple::Generators::RailsOutputBuffer) { text }.precompiled_template
|
87
87
|
end
|
88
|
+
|
89
|
+
def self.parse_inline_erb tracker, text
|
90
|
+
fp = Brakeman::FileParser.new(nil, nil)
|
91
|
+
tp = self.new(tracker, fp)
|
92
|
+
src = tp.parse_erb text
|
93
|
+
type = tp.erubis? ? :erubis : :erb
|
94
|
+
|
95
|
+
return type, fp.parse_ruby(src, "_inline_")
|
96
|
+
end
|
88
97
|
end
|
89
98
|
end
|
@@ -272,6 +272,31 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
|
|
272
272
|
|
273
273
|
type ||= :default
|
274
274
|
value ||= :default
|
275
|
+
|
276
|
+
if type == :inline and string? value and not hash_access(rest, :type)
|
277
|
+
value, rest = make_inline_render(value, rest)
|
278
|
+
end
|
279
|
+
|
275
280
|
return type, value, rest
|
276
281
|
end
|
282
|
+
|
283
|
+
def make_inline_render value, options
|
284
|
+
require 'brakeman/parsers/template_parser'
|
285
|
+
|
286
|
+
class_or_module = (@current_class || @current_module)
|
287
|
+
|
288
|
+
class_or_module = if class_or_module.nil?
|
289
|
+
"Unknown"
|
290
|
+
else
|
291
|
+
class_or_module.name
|
292
|
+
end
|
293
|
+
|
294
|
+
template_name = "#@current_method/inline@#{value.line}:#{class_or_module}".to_sym
|
295
|
+
type, ast = Brakeman::TemplateParser.parse_inline_erb(@tracker, value.value)
|
296
|
+
ast = ast.deep_clone(value.line)
|
297
|
+
@tracker.processor.process_template(template_name, ast, type, nil, @file_name)
|
298
|
+
@tracker.processor.process_template_alias(@tracker.templates[template_name])
|
299
|
+
|
300
|
+
return s(:lit, template_name), options
|
301
|
+
end
|
277
302
|
end
|