brakeman 1.6.2 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 => {},
|