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
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'brakeman/processors/base_processor'
|
2
|
+
require 'brakeman/processors/lib/module_helper'
|
2
3
|
require 'brakeman/tracker/controller'
|
3
4
|
|
4
5
|
#Processes controller. Results are put in tracker.controllers
|
5
6
|
class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
|
7
|
+
include Brakeman::ModuleHelper
|
8
|
+
|
6
9
|
FORMAT_HTML = Sexp.new(:call, Sexp.new(:lvar, :format), :html)
|
7
10
|
|
8
11
|
def initialize app_tree, tracker
|
@@ -47,64 +50,15 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
|
|
47
50
|
return exp
|
48
51
|
end
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
name = (outer_class.name.to_s + "::" + name.to_s).to_sym
|
53
|
-
end
|
54
|
-
|
55
|
-
if @current_module
|
56
|
-
name = (@current_module.name.to_s + "::" + name.to_s).to_sym
|
57
|
-
end
|
58
|
-
|
59
|
-
if @tracker.controllers[name]
|
60
|
-
@current_class = @tracker.controllers[name]
|
61
|
-
@current_class.add_file @file_name, exp
|
62
|
-
else
|
63
|
-
@current_class = Brakeman::Controller.new name, parent, @file_name, exp, @tracker
|
64
|
-
@tracker.controllers[name] = @current_class
|
65
|
-
end
|
66
|
-
|
67
|
-
exp.body = process_all! exp.body
|
68
|
-
set_layout_name
|
69
|
-
|
70
|
-
if outer_class
|
71
|
-
@current_class = outer_class
|
72
|
-
else
|
73
|
-
@current_class = nil
|
53
|
+
handle_class(exp, @tracker.controllers, Brakeman::Controller) do
|
54
|
+
set_layout_name
|
74
55
|
end
|
75
56
|
|
76
57
|
exp
|
77
58
|
end
|
78
59
|
|
79
60
|
def process_module exp, parent = nil
|
80
|
-
|
81
|
-
|
82
|
-
if @current_module
|
83
|
-
outer_module = @current_module
|
84
|
-
name = (outer_module.name.to_s + "::" + name.to_s).to_sym
|
85
|
-
end
|
86
|
-
|
87
|
-
if @current_class
|
88
|
-
name = (@current_class.name.to_s + "::" + name.to_s).to_sym
|
89
|
-
end
|
90
|
-
|
91
|
-
if @tracker.libs[name]
|
92
|
-
@current_module = @tracker.libs[name]
|
93
|
-
@current_module.add_file @file_name, exp
|
94
|
-
else
|
95
|
-
@current_module = Brakeman::Controller.new name, parent, @file_name, exp, @tracker
|
96
|
-
@tracker.libs[name] = @current_module
|
97
|
-
end
|
98
|
-
|
99
|
-
exp.body = process_all! exp.body
|
100
|
-
|
101
|
-
if outer_module
|
102
|
-
@current_module = outer_module
|
103
|
-
else
|
104
|
-
@current_module = nil
|
105
|
-
end
|
106
|
-
|
107
|
-
exp
|
61
|
+
handle_module exp, Brakeman::Controller, parent
|
108
62
|
end
|
109
63
|
|
110
64
|
#Look for specific calls inside the controller
|
@@ -187,53 +141,6 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
|
|
187
141
|
end
|
188
142
|
end
|
189
143
|
|
190
|
-
#Process method definition and store in Tracker
|
191
|
-
def process_defn exp
|
192
|
-
name = exp.method_name
|
193
|
-
@current_method = name
|
194
|
-
res = Sexp.new :defn, name, exp.formal_args, *process_all!(exp.body)
|
195
|
-
res.line(exp.line)
|
196
|
-
@current_method = nil
|
197
|
-
|
198
|
-
if @current_class
|
199
|
-
@current_class.add_method @visibility, name, res, @file_name
|
200
|
-
elsif @current_module
|
201
|
-
@current_module.add_method @visibility, name, res, @file_name
|
202
|
-
end
|
203
|
-
|
204
|
-
res
|
205
|
-
end
|
206
|
-
|
207
|
-
#Process self.method definition and store in Tracker
|
208
|
-
def process_defs exp
|
209
|
-
name = exp.method_name
|
210
|
-
|
211
|
-
if node_type? exp[1], :self
|
212
|
-
if @current_class
|
213
|
-
target = @current_class.name
|
214
|
-
elsif @current_module
|
215
|
-
target = @current_module.name
|
216
|
-
else
|
217
|
-
target = nil
|
218
|
-
end
|
219
|
-
else
|
220
|
-
target = class_name exp[1]
|
221
|
-
end
|
222
|
-
|
223
|
-
@current_method = name
|
224
|
-
res = Sexp.new :defs, target, name, exp.formal_args, *process_all!(exp.body)
|
225
|
-
res.line(exp.line)
|
226
|
-
@current_method = nil
|
227
|
-
|
228
|
-
if @current_class
|
229
|
-
@current_class.add_method @visibility, name, res, @file_name
|
230
|
-
elsif @current_module
|
231
|
-
@current_module.add_method @visibility, name, res, @file_name
|
232
|
-
end
|
233
|
-
|
234
|
-
res
|
235
|
-
end
|
236
|
-
|
237
144
|
#Look for before_filters and add fake ones if necessary
|
238
145
|
def process_iter exp
|
239
146
|
if @current_method.nil? and call? exp.block_call
|
@@ -28,10 +28,7 @@ class Brakeman::ErbTemplateProcessor < Brakeman::TemplateProcessor
|
|
28
28
|
if arg.node_type == :str #ignore plain strings
|
29
29
|
ignore
|
30
30
|
else
|
31
|
-
|
32
|
-
s.line(exp.line)
|
33
|
-
@current_template.add_output s
|
34
|
-
s
|
31
|
+
add_output arg
|
35
32
|
end
|
36
33
|
elsif method == :force_encoding
|
37
34
|
ignore
|
@@ -23,15 +23,9 @@ class Brakeman::ErubisTemplateProcessor < Brakeman::TemplateProcessor
|
|
23
23
|
if arg.node_type == :str #ignore plain strings
|
24
24
|
ignore
|
25
25
|
elsif node_type? target, :ivar and target.value == :@output_buffer
|
26
|
-
|
27
|
-
s.line(exp.line)
|
28
|
-
@current_template.add_output s
|
29
|
-
s
|
26
|
+
add_escaped_output arg
|
30
27
|
else
|
31
|
-
|
32
|
-
s.line(exp.line)
|
33
|
-
@current_template.add_output s
|
34
|
-
s
|
28
|
+
add_output arg
|
35
29
|
end
|
36
30
|
elsif method == :to_s
|
37
31
|
ignore
|
@@ -75,15 +69,9 @@ class Brakeman::ErubisTemplateProcessor < Brakeman::TemplateProcessor
|
|
75
69
|
if arg.node_type == :str
|
76
70
|
ignore
|
77
71
|
elsif safe_append_method?(exp.method)
|
78
|
-
|
79
|
-
s.line(exp.line)
|
80
|
-
@current_template.add_output s
|
81
|
-
s
|
72
|
+
add_output arg
|
82
73
|
else
|
83
|
-
|
84
|
-
s.line(exp.line)
|
85
|
-
@current_template.add_output s
|
86
|
-
s
|
74
|
+
add_escaped_output arg
|
87
75
|
end
|
88
76
|
else
|
89
77
|
super
|
@@ -81,10 +81,7 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
81
81
|
if out.node_type == :str #ignore plain strings
|
82
82
|
ignore
|
83
83
|
else
|
84
|
-
|
85
|
-
@current_template.add_output s
|
86
|
-
s.line(exp.line)
|
87
|
-
s
|
84
|
+
add_output out
|
88
85
|
end
|
89
86
|
elsif target == nil and method == :render
|
90
87
|
#Process call to render()
|
@@ -175,16 +172,12 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
175
172
|
exp.map! { |e| get_pushed_value e }
|
176
173
|
else
|
177
174
|
if call? exp and exp.target == HAML_HELPERS and exp.method == :html_escape
|
178
|
-
|
175
|
+
add_escaped_output exp.first_arg
|
179
176
|
elsif @javascript and call? exp and (exp.method == :j or exp.method == :escape_javascript)
|
180
|
-
|
177
|
+
add_escaped_output exp.first_arg
|
181
178
|
else
|
182
|
-
|
179
|
+
add_output exp, default
|
183
180
|
end
|
184
|
-
|
185
|
-
s.line(exp.line)
|
186
|
-
@current_template.add_output s
|
187
|
-
s
|
188
181
|
end
|
189
182
|
end
|
190
183
|
end
|
@@ -28,11 +28,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
28
28
|
process_all exp.body
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
def process_defs exp
|
33
|
-
return exp unless @current_method
|
34
|
-
process_all exp.body
|
35
|
-
end
|
31
|
+
alias process_defs process_defn
|
36
32
|
|
37
33
|
#Process body of block
|
38
34
|
def process_rlist exp
|
@@ -70,11 +66,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
70
66
|
def process_render exp
|
71
67
|
process exp.last if sexp? exp.last
|
72
68
|
|
73
|
-
|
74
|
-
:method => :render,
|
75
|
-
:call => exp,
|
76
|
-
:nested => false,
|
77
|
-
:location => make_location }
|
69
|
+
add_simple_call :render, exp
|
78
70
|
|
79
71
|
exp
|
80
72
|
end
|
@@ -84,11 +76,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
84
76
|
def process_dxstr exp
|
85
77
|
process exp.last if sexp? exp.last
|
86
78
|
|
87
|
-
|
88
|
-
:method => :`,
|
89
|
-
:call => exp,
|
90
|
-
:nested => false,
|
91
|
-
:location => make_location }
|
79
|
+
add_simple_call :`, exp
|
92
80
|
|
93
81
|
exp
|
94
82
|
end
|
@@ -97,11 +85,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
97
85
|
def process_dsym exp
|
98
86
|
exp.each { |arg| process arg if sexp? arg }
|
99
87
|
|
100
|
-
|
101
|
-
:method => :literal_to_sym,
|
102
|
-
:call => exp,
|
103
|
-
:nested => false,
|
104
|
-
:location => make_location }
|
88
|
+
add_simple_call :literal_to_sym, exp
|
105
89
|
|
106
90
|
exp
|
107
91
|
end
|
@@ -110,11 +94,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
110
94
|
def process_dregx exp
|
111
95
|
exp.each { |arg| process arg if sexp? arg }
|
112
96
|
|
113
|
-
|
114
|
-
:method => :brakeman_regex_interp,
|
115
|
-
:call => exp,
|
116
|
-
:nested => false,
|
117
|
-
:location => make_location }
|
97
|
+
add_simple_call :brakeman_regex_interp, exp
|
118
98
|
|
119
99
|
exp
|
120
100
|
end
|
@@ -126,6 +106,14 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
126
106
|
|
127
107
|
private
|
128
108
|
|
109
|
+
def add_simple_call method_name, exp
|
110
|
+
@calls << { :target => nil,
|
111
|
+
:method => method_name,
|
112
|
+
:call => exp,
|
113
|
+
:nested => false,
|
114
|
+
:location => make_location }
|
115
|
+
end
|
116
|
+
|
129
117
|
#Gets the target of a call as a Symbol
|
130
118
|
#if possible
|
131
119
|
def get_target exp, include_calls = false
|
@@ -65,7 +65,7 @@ class Brakeman::FindReturnValue
|
|
65
65
|
@uses_ivars = true if node_type? current, :ivar
|
66
66
|
|
67
67
|
if node_type? current, :return
|
68
|
-
@return_values << current.value
|
68
|
+
@return_values << last_value(current.value) if current.value
|
69
69
|
elsif sexp? current
|
70
70
|
todo = current[1..-1].concat todo
|
71
71
|
end
|
@@ -97,10 +97,40 @@ class Brakeman::FindReturnValue
|
|
97
97
|
true_branch or false_branch
|
98
98
|
end
|
99
99
|
end
|
100
|
-
when :lasgn, :iasgn
|
101
|
-
exp.rhs
|
100
|
+
when :lasgn, :iasgn, :op_asgn_or, :attrasgn
|
101
|
+
last_value exp.rhs
|
102
|
+
when :rescue
|
103
|
+
values = []
|
104
|
+
|
105
|
+
exp.each_sexp do |e|
|
106
|
+
if node_type? e, :resbody
|
107
|
+
if e.last
|
108
|
+
values << last_value(e.last)
|
109
|
+
end
|
110
|
+
elsif sexp? e
|
111
|
+
values << last_value(e)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
values.reject! do |v|
|
116
|
+
v.nil? or node_type? v, :nil
|
117
|
+
end
|
118
|
+
|
119
|
+
if values.length > 1
|
120
|
+
values.inject do |m, v|
|
121
|
+
make_or(m, v)
|
122
|
+
end
|
123
|
+
else
|
124
|
+
values.first
|
125
|
+
end
|
102
126
|
when :return
|
103
|
-
exp.value
|
127
|
+
if exp.value
|
128
|
+
last_value exp.value
|
129
|
+
else
|
130
|
+
nil
|
131
|
+
end
|
132
|
+
when :nil
|
133
|
+
nil
|
104
134
|
else
|
105
135
|
exp.original_line = exp.line unless exp.original_line
|
106
136
|
exp
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Brakeman::ModuleHelper
|
2
|
+
def handle_module exp, tracker_class, parent = nil
|
3
|
+
name = class_name(exp.module_name)
|
4
|
+
|
5
|
+
if @current_module
|
6
|
+
outer_module = @current_module
|
7
|
+
name = (outer_module.name.to_s + "::" + name.to_s).to_sym
|
8
|
+
end
|
9
|
+
|
10
|
+
if @current_class
|
11
|
+
name = (@current_class.name.to_s + "::" + name.to_s).to_sym
|
12
|
+
end
|
13
|
+
|
14
|
+
if @tracker.libs[name]
|
15
|
+
@current_module = @tracker.libs[name]
|
16
|
+
@current_module.add_file @file_name, exp
|
17
|
+
else
|
18
|
+
@current_module = tracker_class.new name, parent, @file_name, exp, @tracker
|
19
|
+
@tracker.libs[name] = @current_module
|
20
|
+
end
|
21
|
+
|
22
|
+
exp.body = process_all! exp.body
|
23
|
+
|
24
|
+
if outer_module
|
25
|
+
@current_module = outer_module
|
26
|
+
else
|
27
|
+
@current_module = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
exp
|
31
|
+
end
|
32
|
+
|
33
|
+
def handle_class exp, collection, tracker_class
|
34
|
+
name = class_name(exp.class_name)
|
35
|
+
parent = class_name exp.parent_name
|
36
|
+
|
37
|
+
if @current_class
|
38
|
+
outer_class = @current_class
|
39
|
+
name = (outer_class.name.to_s + "::" + name.to_s).to_sym
|
40
|
+
end
|
41
|
+
|
42
|
+
if @current_module
|
43
|
+
name = (@current_module.name.to_s + "::" + name.to_s).to_sym
|
44
|
+
end
|
45
|
+
|
46
|
+
if collection[name]
|
47
|
+
@current_class = collection[name]
|
48
|
+
@current_class.add_file @file_name, exp
|
49
|
+
else
|
50
|
+
@current_class = tracker_class.new name, parent, @file_name, exp, @tracker
|
51
|
+
collection[name] = @current_class
|
52
|
+
end
|
53
|
+
|
54
|
+
exp.body = process_all! exp.body
|
55
|
+
|
56
|
+
yield if block_given?
|
57
|
+
|
58
|
+
if outer_class
|
59
|
+
@current_class = outer_class
|
60
|
+
else
|
61
|
+
@current_class = nil
|
62
|
+
end
|
63
|
+
|
64
|
+
exp
|
65
|
+
end
|
66
|
+
|
67
|
+
def process_defs exp
|
68
|
+
name = exp.method_name
|
69
|
+
|
70
|
+
if node_type? exp[1], :self
|
71
|
+
if @current_class
|
72
|
+
target = @current_class.name
|
73
|
+
elsif @current_module
|
74
|
+
target = @current_module.name
|
75
|
+
else
|
76
|
+
target = nil
|
77
|
+
end
|
78
|
+
else
|
79
|
+
target = class_name exp[1]
|
80
|
+
end
|
81
|
+
|
82
|
+
@current_method = name
|
83
|
+
res = Sexp.new :defs, target, name, exp.formal_args, *process_all!(exp.body)
|
84
|
+
res.line(exp.line)
|
85
|
+
@current_method = nil
|
86
|
+
|
87
|
+
if @current_class
|
88
|
+
@current_class.add_method @visibility, name, res, @file_name
|
89
|
+
elsif @current_module
|
90
|
+
@current_module.add_method @visibility, name, res, @file_name
|
91
|
+
end
|
92
|
+
res
|
93
|
+
end
|
94
|
+
|
95
|
+
def process_defn exp
|
96
|
+
name = exp.method_name
|
97
|
+
|
98
|
+
@current_method = name
|
99
|
+
res = Sexp.new :defn, name, exp.formal_args, *process_all!(exp.body)
|
100
|
+
res.line(exp.line)
|
101
|
+
@current_method = nil
|
102
|
+
|
103
|
+
if @current_class
|
104
|
+
@current_class.add_method @visibility, name, res, @file_name
|
105
|
+
elsif @current_module
|
106
|
+
@current_module.add_method @visibility, name, res, @file_name
|
107
|
+
end
|
108
|
+
|
109
|
+
res
|
110
|
+
end
|
111
|
+
end
|