brakeman-lib 3.3.2 → 3.3.3
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 +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
|