brakeman 1.6.2 → 1.7.0
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.
- data/lib/brakeman/checks.rb +14 -5
- data/lib/brakeman/checks/base_check.rb +19 -7
- data/lib/brakeman/checks/check_digest_dos.rb +37 -0
- data/lib/brakeman/checks/check_escape_function.rb +2 -1
- data/lib/brakeman/checks/check_file_access.rb +40 -23
- data/lib/brakeman/checks/check_filter_skipping.rb +2 -1
- data/lib/brakeman/checks/check_forgery_setting.rb +7 -4
- data/lib/brakeman/checks/check_link_to.rb +6 -3
- data/lib/brakeman/checks/check_link_to_href.rb +4 -2
- data/lib/brakeman/checks/check_nested_attributes.rb +3 -2
- data/lib/brakeman/checks/check_quote_table_name.rb +2 -1
- data/lib/brakeman/checks/check_response_splitting.rb +2 -1
- data/lib/brakeman/checks/check_sql.rb +10 -7
- data/lib/brakeman/checks/check_strip_tags.rb +2 -1
- data/lib/brakeman/checks/check_validation_regex.rb +1 -1
- data/lib/brakeman/checks/check_without_protection.rb +2 -9
- data/lib/brakeman/format/style.css +4 -0
- data/lib/brakeman/processors/alias_processor.rb +10 -10
- data/lib/brakeman/processors/base_processor.rb +4 -11
- data/lib/brakeman/processors/controller_processor.rb +9 -1
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +96 -31
- data/lib/brakeman/processors/lib/render_helper.rb +3 -2
- data/lib/brakeman/processors/lib/route_helper.rb +21 -0
- data/lib/brakeman/processors/library_processor.rb +10 -1
- data/lib/brakeman/processors/model_processor.rb +8 -1
- data/lib/brakeman/processors/template_processor.rb +0 -1
- data/lib/brakeman/report.rb +10 -0
- data/lib/brakeman/scanner.rb +2 -0
- data/lib/brakeman/util.rb +1 -2
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +19 -1
- data/lib/ruby_parser/bm_sexp_processor.rb +231 -0
- metadata +81 -79
@@ -14,17 +14,10 @@ class Brakeman::CheckWithoutProtection < Brakeman::BaseCheck
|
|
14
14
|
return
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
tracker.models.each do |name, m|
|
19
|
-
if ancestor? m, :"ActiveRecord::Base"
|
20
|
-
models << name
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
return if models.empty?
|
17
|
+
return if active_record_models.empty?
|
25
18
|
|
26
19
|
Brakeman.debug "Finding all mass assignments"
|
27
|
-
calls = tracker.find_call :targets =>
|
20
|
+
calls = tracker.find_call :targets => active_record_models.keys, :methods => [:new,
|
28
21
|
:attributes=,
|
29
22
|
:update_attributes,
|
30
23
|
:update_attributes!,
|
@@ -1,12 +1,11 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'sexp_processor'
|
3
1
|
require 'brakeman/util'
|
2
|
+
require 'ruby_parser/bm_sexp_processor'
|
4
3
|
require 'brakeman/processors/lib/processor_helper'
|
5
4
|
|
6
5
|
#Returns an s-expression with aliases replaced with their value.
|
7
6
|
#This does not preserve semantics (due to side effects, etc.), but it makes
|
8
7
|
#processing easier when searching for various things.
|
9
|
-
class Brakeman::AliasProcessor < SexpProcessor
|
8
|
+
class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
10
9
|
include Brakeman::ProcessorHelper
|
11
10
|
include Brakeman::Util
|
12
11
|
|
@@ -19,11 +18,6 @@ class Brakeman::AliasProcessor < SexpProcessor
|
|
19
18
|
# AliasProcessor.new.process_safely src
|
20
19
|
def initialize tracker = nil
|
21
20
|
super()
|
22
|
-
self.strict = false
|
23
|
-
self.auto_shift_type = false
|
24
|
-
self.require_empty = false
|
25
|
-
self.default_method = :process_default
|
26
|
-
self.warn_on_default = false
|
27
21
|
@env = SexpProcessor::Environment.new
|
28
22
|
@inside_if = false
|
29
23
|
@ignore_ifs = false
|
@@ -368,7 +362,11 @@ class Brakeman::AliasProcessor < SexpProcessor
|
|
368
362
|
match = Sexp.new(:call, target, :[], Sexp.new(:arglist, index))
|
369
363
|
|
370
364
|
unless env[match]
|
371
|
-
|
365
|
+
if request_value? target
|
366
|
+
env[match] = Sexp.new(:or, match, value)
|
367
|
+
else
|
368
|
+
env[match] = value
|
369
|
+
end
|
372
370
|
end
|
373
371
|
|
374
372
|
exp
|
@@ -452,7 +450,9 @@ class Brakeman::AliasProcessor < SexpProcessor
|
|
452
450
|
def process_array_access target, args
|
453
451
|
if args.length == 1 and integer? args[0]
|
454
452
|
index = args[0][1]
|
455
|
-
|
453
|
+
|
454
|
+
#Have to do this because first element is :array and we have to skip it
|
455
|
+
target[1..-1][index + 1]
|
456
456
|
else
|
457
457
|
nil
|
458
458
|
end
|
@@ -1,10 +1,8 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'sexp_processor'
|
3
1
|
require 'brakeman/processors/lib/processor_helper'
|
4
2
|
require 'brakeman/util'
|
5
3
|
|
6
4
|
#Base processor for most processors.
|
7
|
-
class Brakeman::BaseProcessor < SexpProcessor
|
5
|
+
class Brakeman::BaseProcessor < Brakeman::SexpProcessor
|
8
6
|
include Brakeman::ProcessorHelper
|
9
7
|
include Brakeman::Util
|
10
8
|
|
@@ -13,11 +11,6 @@ class Brakeman::BaseProcessor < SexpProcessor
|
|
13
11
|
#Return a new Processor.
|
14
12
|
def initialize tracker
|
15
13
|
super()
|
16
|
-
self.strict = false
|
17
|
-
self.auto_shift_type = false
|
18
|
-
self.require_empty = false
|
19
|
-
self.default_method = :process_default
|
20
|
-
self.warn_on_default = false
|
21
14
|
@last = nil
|
22
15
|
@tracker = tracker
|
23
16
|
@ignore = Sexp.new :ignore
|
@@ -50,7 +43,7 @@ class Brakeman::BaseProcessor < SexpProcessor
|
|
50
43
|
#Default processing.
|
51
44
|
def process_default exp
|
52
45
|
exp = exp.dup
|
53
|
-
|
46
|
+
|
54
47
|
exp.each_with_index do |e, i|
|
55
48
|
if sexp? e and not e.empty?
|
56
49
|
exp[i] = process e
|
@@ -58,8 +51,8 @@ class Brakeman::BaseProcessor < SexpProcessor
|
|
58
51
|
e
|
59
52
|
end
|
60
53
|
end
|
61
|
-
|
62
|
-
exp
|
54
|
+
|
55
|
+
exp
|
63
56
|
end
|
64
57
|
|
65
58
|
#Process an if statement.
|
@@ -30,8 +30,16 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
|
|
30
30
|
if @current_module
|
31
31
|
name = (@current_module.to_s + "::" + name.to_s).to_sym
|
32
32
|
end
|
33
|
+
|
34
|
+
begin
|
35
|
+
parent = class_name exp[2]
|
36
|
+
rescue StandardError => e
|
37
|
+
Brakeman.debug e
|
38
|
+
parent = nil
|
39
|
+
end
|
40
|
+
|
33
41
|
@controller = { :name => name,
|
34
|
-
:parent =>
|
42
|
+
:parent => parent,
|
35
43
|
:includes => [],
|
36
44
|
:public => {},
|
37
45
|
:private => {},
|
@@ -14,6 +14,7 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
14
14
|
@prefix = [] #Controller name prefix (a module name, usually)
|
15
15
|
@current_controller = nil
|
16
16
|
@with_options = nil #For use inside map.with_options
|
17
|
+
@controller_block = false
|
17
18
|
end
|
18
19
|
|
19
20
|
def process_routes exp
|
@@ -49,6 +50,8 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
49
50
|
process_resources_block exp
|
50
51
|
when :scope
|
51
52
|
process_scope_block exp
|
53
|
+
when :controller
|
54
|
+
process_controller_block exp
|
52
55
|
else
|
53
56
|
super
|
54
57
|
end
|
@@ -71,11 +74,8 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
71
74
|
args = exp[3][1..-1]
|
72
75
|
|
73
76
|
if value = hash_access(args[0], :to)
|
74
|
-
if string? value
|
75
|
-
|
76
|
-
|
77
|
-
self.current_controller = controller
|
78
|
-
@tracker.routes[@current_controller] << action.to_sym
|
77
|
+
if string? value
|
78
|
+
add_route_from_string value
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -97,19 +97,36 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
97
97
|
return exp
|
98
98
|
elsif matcher.include? ':action'
|
99
99
|
action_variable = true
|
100
|
+
elsif args[1].nil? and in_controller_block? and not matcher.include? ":"
|
101
|
+
add_route matcher
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
103
105
|
if hash? args[-1]
|
104
106
|
hash_iterate args[-1] do |k, v|
|
105
|
-
if string? k
|
106
|
-
|
107
|
+
if string? k
|
108
|
+
if string? v
|
109
|
+
add_route_from_string v[1]
|
110
|
+
elsif in_controller_block? and symbol? v
|
111
|
+
add_route v
|
112
|
+
end
|
113
|
+
elsif symbol? k
|
114
|
+
case k[1]
|
115
|
+
when :action
|
116
|
+
if string? v
|
117
|
+
add_route_from_string v
|
118
|
+
else
|
119
|
+
add_route v
|
120
|
+
end
|
107
121
|
|
108
|
-
self.current_controller = controller
|
109
|
-
@tracker.routes[@current_controller] << action.to_sym if action
|
110
|
-
elsif symbol? k and k[1] == :action
|
111
|
-
@tracker.routes[@current_controller] << v[1].to_sym
|
112
122
|
action_variable = false
|
123
|
+
when :to
|
124
|
+
if string? v
|
125
|
+
add_route_from_string v[1]
|
126
|
+
elsif in_controller_block? and symbol? v
|
127
|
+
add_route v
|
128
|
+
end
|
129
|
+
end
|
113
130
|
end
|
114
131
|
end
|
115
132
|
end
|
@@ -118,44 +135,59 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
118
135
|
@tracker.routes[@current_controller] = :allow_all_actions
|
119
136
|
end
|
120
137
|
|
138
|
+
@current_controller = nil unless in_controller_block?
|
121
139
|
exp
|
122
140
|
end
|
123
141
|
|
142
|
+
def add_route_from_string value
|
143
|
+
value = value[1] if string? value
|
144
|
+
|
145
|
+
controller, action = extract_action value
|
146
|
+
|
147
|
+
if action
|
148
|
+
add_route action, controller
|
149
|
+
elsif in_controller_block?
|
150
|
+
add_route value
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
124
154
|
def process_verb exp
|
125
155
|
args = exp[3][1..-1]
|
126
156
|
|
127
157
|
if symbol? args[0] and not hash? args[1]
|
128
|
-
|
158
|
+
add_route args[0]
|
129
159
|
elsif hash? args[1]
|
130
160
|
hash_iterate args[1] do |k, v|
|
131
|
-
if symbol? k and k[1] == :to
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
161
|
+
if symbol? k and k[1] == :to
|
162
|
+
if string? v
|
163
|
+
add_route_from_string v[1]
|
164
|
+
elsif in_controller_block? and symbol? v
|
165
|
+
add_route v
|
166
|
+
end
|
136
167
|
end
|
137
168
|
end
|
138
169
|
elsif string? args[0]
|
139
170
|
route = args[0][1].split "/"
|
140
171
|
if route.length != 2
|
141
|
-
|
172
|
+
add_route route[0]
|
142
173
|
else
|
143
|
-
|
144
|
-
@tracker.routes[@current_controller] << route[1].to_sym
|
145
|
-
@current_controller = nil
|
174
|
+
add_route route[1], route[0]
|
146
175
|
end
|
176
|
+
elsif in_controller_block? and symbol? args[0]
|
177
|
+
add_route args[0]
|
147
178
|
else hash? args[0]
|
148
179
|
hash_iterate args[0] do |k, v|
|
149
|
-
if string?
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
180
|
+
if string? k
|
181
|
+
if string? v
|
182
|
+
add_route_from_string v
|
183
|
+
elsif in_controller_block?
|
184
|
+
add_route v
|
185
|
+
end
|
155
186
|
end
|
156
187
|
end
|
157
188
|
end
|
158
189
|
|
190
|
+
@current_controller = nil unless in_controller_block?
|
159
191
|
exp
|
160
192
|
end
|
161
193
|
|
@@ -171,6 +203,7 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
171
203
|
end
|
172
204
|
end
|
173
205
|
|
206
|
+
@current_controller = nil unless in_controller_block?
|
174
207
|
exp
|
175
208
|
end
|
176
209
|
|
@@ -186,18 +219,27 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
186
219
|
end
|
187
220
|
end
|
188
221
|
|
222
|
+
@current_controller = nil unless in_controller_block?
|
189
223
|
exp
|
190
224
|
end
|
191
225
|
|
192
226
|
def process_resources_block exp
|
193
|
-
|
194
|
-
|
227
|
+
in_controller_block do
|
228
|
+
process_resources exp[1]
|
229
|
+
process exp[3]
|
230
|
+
end
|
231
|
+
|
232
|
+
@current_controller = nil
|
195
233
|
exp
|
196
234
|
end
|
197
235
|
|
198
236
|
def process_resource_block exp
|
199
|
-
|
200
|
-
|
237
|
+
in_controller_block do
|
238
|
+
process_resource exp[1]
|
239
|
+
process exp[3]
|
240
|
+
end
|
241
|
+
|
242
|
+
@current_controller = nil
|
201
243
|
exp
|
202
244
|
end
|
203
245
|
|
@@ -207,7 +249,30 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
207
249
|
exp
|
208
250
|
end
|
209
251
|
|
252
|
+
def process_controller_block exp
|
253
|
+
args = exp[1][3]
|
254
|
+
self.current_controller = args[1][1]
|
255
|
+
|
256
|
+
in_controller_block do
|
257
|
+
process exp[-1] if exp[-1]
|
258
|
+
end
|
259
|
+
|
260
|
+
@current_controller = nil
|
261
|
+
exp
|
262
|
+
end
|
263
|
+
|
210
264
|
def extract_action str
|
211
265
|
str.split "#"
|
212
266
|
end
|
267
|
+
|
268
|
+
def in_controller_block?
|
269
|
+
@controller_block
|
270
|
+
end
|
271
|
+
|
272
|
+
def in_controller_block
|
273
|
+
prev_block = @controller_block
|
274
|
+
@controller_block = true
|
275
|
+
yield
|
276
|
+
@controller_block = prev_block
|
277
|
+
end
|
213
278
|
end
|
@@ -15,7 +15,6 @@ module Brakeman::RenderHelper
|
|
15
15
|
process_template template_name, exp[3]
|
16
16
|
rescue ArgumentError => e
|
17
17
|
Brakeman.debug "Problem processing render: #{exp}"
|
18
|
-
raise e
|
19
18
|
end
|
20
19
|
when :partial, :layout
|
21
20
|
process_partial exp[2], exp[3]
|
@@ -48,7 +47,9 @@ module Brakeman::RenderHelper
|
|
48
47
|
|
49
48
|
#Processes a given action
|
50
49
|
def process_action name, args
|
51
|
-
|
50
|
+
if name.is_a? String or name.is_a? Symbol
|
51
|
+
process_template template_name(name), args
|
52
|
+
end
|
52
53
|
end
|
53
54
|
|
54
55
|
#Processes a template, adding any instance variables
|
@@ -21,6 +21,27 @@ module Brakeman::RouteHelper
|
|
21
21
|
@tracker.routes[@current_controller] ||= Set.new
|
22
22
|
end
|
23
23
|
|
24
|
+
#Add route to controller. If a controller is specified,
|
25
|
+
#the current controller will be set to that controller.
|
26
|
+
#If no controller is specified, uses current controller value.
|
27
|
+
def add_route route, controller = nil
|
28
|
+
if node_type? route, :str, :lit
|
29
|
+
route = route[1]
|
30
|
+
end
|
31
|
+
|
32
|
+
route = route.to_sym
|
33
|
+
|
34
|
+
if controller
|
35
|
+
self.current_controller = controller
|
36
|
+
end
|
37
|
+
|
38
|
+
routes = @tracker.routes[@current_controller]
|
39
|
+
|
40
|
+
if routes and routes != :allow_all_actions
|
41
|
+
routes << route
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
24
45
|
#Add default routes
|
25
46
|
def add_resources_routes
|
26
47
|
existing_routes = @tracker.routes[@current_controller]
|
@@ -30,8 +30,15 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
|
|
30
30
|
if @tracker.libs[name]
|
31
31
|
@current_class = @tracker.libs[name]
|
32
32
|
else
|
33
|
+
begin
|
34
|
+
parent = class_name exp[2]
|
35
|
+
rescue StandardError => e
|
36
|
+
Brakeman.debug e
|
37
|
+
parent = nil
|
38
|
+
end
|
39
|
+
|
33
40
|
@current_class = { :name => name,
|
34
|
-
:parent =>
|
41
|
+
:parent => parent,
|
35
42
|
:includes => [],
|
36
43
|
:public => {},
|
37
44
|
:private => {},
|
@@ -91,6 +98,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
|
|
91
98
|
end
|
92
99
|
|
93
100
|
def process_defn exp
|
101
|
+
exp = @alias_processor.process exp
|
94
102
|
exp[0] = :methdef
|
95
103
|
|
96
104
|
if @current_class
|
@@ -103,6 +111,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
|
|
103
111
|
end
|
104
112
|
|
105
113
|
def process_defs exp
|
114
|
+
exp = @alias_processor.process exp
|
106
115
|
exp[0] = :selfdef
|
107
116
|
|
108
117
|
if @current_class
|
@@ -22,8 +22,15 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
|
|
22
22
|
Brakeman.debug "[Notice] Skipping inner class: #{class_name exp[1]}"
|
23
23
|
ignore
|
24
24
|
else
|
25
|
+
begin
|
26
|
+
parent = class_name exp[2]
|
27
|
+
rescue StandardError => e
|
28
|
+
Brakeman.debug e
|
29
|
+
parent = nil
|
30
|
+
end
|
31
|
+
|
25
32
|
@model = { :name => class_name(exp[1]),
|
26
|
-
:parent =>
|
33
|
+
:parent => parent,
|
27
34
|
:includes => [],
|
28
35
|
:public => {},
|
29
36
|
:private => {},
|