brakeman 0.3.0 → 0.3.1
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/bin/brakeman +4 -0
- data/lib/processors/lib/find_call.rb +13 -1
- data/lib/processors/lib/find_model_call.rb +5 -1
- data/lib/processors/lib/rails2_route_processor.rb +304 -0
- data/lib/processors/lib/rails3_route_processor.rb +172 -0
- data/lib/processors/lib/route_helper.rb +34 -0
- data/lib/processors/route_processor.rb +5 -332
- data/lib/report.rb +3 -1
- data/lib/scanner.rb +1 -0
- data/lib/version.rb +1 -1
- metadata +46 -35
data/bin/brakeman
CHANGED
@@ -31,13 +31,14 @@ require 'processors/base_processor'
|
|
31
31
|
# FindCall.new nil, /^g?sub!?$/
|
32
32
|
class FindCall < BaseProcessor
|
33
33
|
|
34
|
-
def initialize targets, methods
|
34
|
+
def initialize targets, methods, in_depth = false
|
35
35
|
super(nil)
|
36
36
|
@calls = []
|
37
37
|
@find_targets = targets
|
38
38
|
@find_methods = methods
|
39
39
|
@current_class = nil
|
40
40
|
@current_method = nil
|
41
|
+
@in_depth = in_depth
|
41
42
|
end
|
42
43
|
|
43
44
|
#Returns a list of results.
|
@@ -97,6 +98,17 @@ class FindCall < BaseProcessor
|
|
97
98
|
else
|
98
99
|
@calls << Sexp.new(:result, @current_class, @current_method, exp).line(exp.line)
|
99
100
|
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
#Normally FindCall won't match a method invocation that is the target of
|
105
|
+
#another call, such as:
|
106
|
+
#
|
107
|
+
# User.find(:first, :conditions => "user = '#{params['user']}').name
|
108
|
+
#
|
109
|
+
#A search for User.find will not match this unless @in_depth is true.
|
110
|
+
if @in_depth and sexp? exp[1] and exp[1][0] == :call
|
111
|
+
process exp[1]
|
100
112
|
end
|
101
113
|
|
102
114
|
exp
|
@@ -6,7 +6,11 @@ class FindModelCall < FindCall
|
|
6
6
|
|
7
7
|
#Passes +targets+ to FindCall
|
8
8
|
def initialize targets
|
9
|
-
|
9
|
+
if OPTIONS[:rails3]
|
10
|
+
super(targets, /^(find.*|first|last|all|where|order|group|having)$/, true)
|
11
|
+
else
|
12
|
+
super(targets, /^(find.*|first|last|all)$/, true)
|
13
|
+
end
|
10
14
|
end
|
11
15
|
|
12
16
|
#Matches entire method chain as a target. This differs from
|
@@ -0,0 +1,304 @@
|
|
1
|
+
require 'processors/base_processor'
|
2
|
+
#Processes the Sexp from routes.rb. Stores results in tracker.routes.
|
3
|
+
#
|
4
|
+
#Note that it is only interested in determining what methods on which
|
5
|
+
#controllers are used as routes, not the generated URLs for routes.
|
6
|
+
class RoutesProcessor < BaseProcessor
|
7
|
+
include RouteHelper
|
8
|
+
|
9
|
+
attr_reader :map, :nested, :current_controller
|
10
|
+
|
11
|
+
def initialize tracker
|
12
|
+
super
|
13
|
+
@map = Sexp.new(:lvar, :map)
|
14
|
+
@nested = nil #used for identifying nested targets
|
15
|
+
@prefix = [] #Controller name prefix (a module name, usually)
|
16
|
+
@current_controller = nil
|
17
|
+
@with_options = nil #For use inside map.with_options
|
18
|
+
end
|
19
|
+
|
20
|
+
#Call this with parsed route file information.
|
21
|
+
#
|
22
|
+
#This method first calls RouteAliasProcessor#process_safely on the +exp+,
|
23
|
+
#so it does not modify the +exp+.
|
24
|
+
def process_routes exp
|
25
|
+
process RouteAliasProcessor.new.process_safely(exp)
|
26
|
+
end
|
27
|
+
|
28
|
+
#Looking for mapping of routes
|
29
|
+
def process_call exp
|
30
|
+
target = exp[1]
|
31
|
+
|
32
|
+
if target == map or target == nested
|
33
|
+
process_map exp
|
34
|
+
|
35
|
+
else
|
36
|
+
process_default exp
|
37
|
+
end
|
38
|
+
|
39
|
+
exp
|
40
|
+
end
|
41
|
+
|
42
|
+
#Process a map.something call
|
43
|
+
#based on the method used
|
44
|
+
def process_map exp
|
45
|
+
args = exp[3][1..-1]
|
46
|
+
|
47
|
+
case exp[2]
|
48
|
+
when :resource
|
49
|
+
process_resource args
|
50
|
+
when :resources
|
51
|
+
process_resources args
|
52
|
+
when :connect, :root
|
53
|
+
process_connect args
|
54
|
+
else
|
55
|
+
process_named_route args
|
56
|
+
end
|
57
|
+
|
58
|
+
exp
|
59
|
+
end
|
60
|
+
|
61
|
+
#Look for map calls that take a block.
|
62
|
+
#Otherwise, just do the default processing.
|
63
|
+
def process_iter exp
|
64
|
+
if exp[1][1] == map or exp[1][1] == nested
|
65
|
+
method = exp[1][2]
|
66
|
+
case method
|
67
|
+
when :namespace
|
68
|
+
process_namespace exp
|
69
|
+
when :resources, :resource
|
70
|
+
process_resources exp[1][3][1..-1]
|
71
|
+
process_default exp[3]
|
72
|
+
when :with_options
|
73
|
+
process_with_options exp
|
74
|
+
end
|
75
|
+
exp
|
76
|
+
else
|
77
|
+
super
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#Process
|
82
|
+
# map.resources :x, :controller => :y, :member => ...
|
83
|
+
#etc.
|
84
|
+
def process_resources exp
|
85
|
+
controller = check_for_controller_name exp
|
86
|
+
if controller
|
87
|
+
self.current_controller = controller
|
88
|
+
process_resource_options exp[-1]
|
89
|
+
else
|
90
|
+
exp.each do |argument|
|
91
|
+
if sexp? argument and argument.node_type == :lit
|
92
|
+
self.current_controller = exp[0][1]
|
93
|
+
add_resources_routes
|
94
|
+
process_resource_options exp[-1]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
#Process all the options that might be in the hash passed to
|
101
|
+
#map.resource, et al.
|
102
|
+
def process_resource_options exp
|
103
|
+
if exp.nil? and @with_options
|
104
|
+
exp = @with_options
|
105
|
+
elsif @with_options
|
106
|
+
exp = exp.concat @with_options[1..-1]
|
107
|
+
end
|
108
|
+
return unless exp.node_type == :hash
|
109
|
+
|
110
|
+
hash_iterate(exp) do |option, value|
|
111
|
+
case option[1]
|
112
|
+
when :controller, :requirements, :singular, :path_prefix, :as,
|
113
|
+
:path_names, :shallow, :name_prefix
|
114
|
+
#should be able to skip
|
115
|
+
when :collection, :member, :new
|
116
|
+
process_collection value
|
117
|
+
when :has_one
|
118
|
+
save_controller = current_controller
|
119
|
+
process_resource value[1..-1]
|
120
|
+
self.current_controller = save_controller
|
121
|
+
when :has_many
|
122
|
+
save_controller = current_controller
|
123
|
+
process_resources value[1..-1]
|
124
|
+
self.current_controller = save_controller
|
125
|
+
when :only
|
126
|
+
process_option_only value
|
127
|
+
when :except
|
128
|
+
process_option_except value
|
129
|
+
else
|
130
|
+
raise "Unhandled resource option: #{option}"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
#Process route option :only => ...
|
136
|
+
def process_option_only exp
|
137
|
+
routes = @tracker.routes[@current_controller]
|
138
|
+
[:index, :new, :create, :show, :edit, :update, :destroy].each do |r|
|
139
|
+
routes.delete r
|
140
|
+
end
|
141
|
+
|
142
|
+
if exp.node_type == :array
|
143
|
+
exp[1..-1].each do |e|
|
144
|
+
routes << e[1]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
#Process route option :except => ...
|
150
|
+
def process_option_except exp
|
151
|
+
return unless exp.node_type == :array
|
152
|
+
routes = @tracker.routes[@current_controller]
|
153
|
+
|
154
|
+
exp[1..-1].each do |e|
|
155
|
+
routes.delete e[1]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# map.resource :x, ..
|
160
|
+
def process_resource exp
|
161
|
+
controller = check_for_controller_name exp
|
162
|
+
if controller
|
163
|
+
self.current_controller = controller
|
164
|
+
process_resource_options exp[-1]
|
165
|
+
else
|
166
|
+
exp.each do |argument|
|
167
|
+
if argument.node_type == :lit
|
168
|
+
self.current_controller = pluralize(exp[0][1].to_s)
|
169
|
+
add_resource_routes
|
170
|
+
process_resource_options exp[-1]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
#Process
|
177
|
+
# map.connect '/something', :controller => 'blah', :action => 'whatever'
|
178
|
+
def process_connect exp
|
179
|
+
controller = check_for_controller_name exp
|
180
|
+
self.current_controller = controller if controller
|
181
|
+
|
182
|
+
#Check for default route
|
183
|
+
if string? exp[0]
|
184
|
+
if exp[0][1] == ":controller/:action/:id"
|
185
|
+
@tracker.routes[:allow_all_actions] = exp[0]
|
186
|
+
elsif exp[0][1].include? ":action"
|
187
|
+
@tracker.routes[@current_controller] = :allow_all_actions
|
188
|
+
return
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
#This -seems- redundant, but people might connect actions
|
193
|
+
#to a controller which already allows them all
|
194
|
+
return if @tracker.routes[@current_controller] == :allow_all_actions
|
195
|
+
|
196
|
+
exp[-1].each_with_index do |e,i|
|
197
|
+
if symbol? e and e[1] == :action
|
198
|
+
@tracker.routes[@current_controller] << exp[-1][i + 1][1].to_sym
|
199
|
+
return
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# map.with_options :controller => 'something' do |something|
|
205
|
+
# something.resources :blah
|
206
|
+
# end
|
207
|
+
def process_with_options exp
|
208
|
+
@with_options = exp[1][3][-1]
|
209
|
+
@nested = Sexp.new(:lvar, exp[2][1])
|
210
|
+
|
211
|
+
self.current_controller = check_for_controller_name exp[1][3]
|
212
|
+
|
213
|
+
#process block
|
214
|
+
process exp[3]
|
215
|
+
|
216
|
+
@with_options = nil
|
217
|
+
@nested = nil
|
218
|
+
end
|
219
|
+
|
220
|
+
# map.namespace :something do |something|
|
221
|
+
# something.resources :blah
|
222
|
+
# end
|
223
|
+
def process_namespace exp
|
224
|
+
call = exp[1]
|
225
|
+
formal_args = exp[2]
|
226
|
+
block = exp[3]
|
227
|
+
|
228
|
+
@prefix << camelize(call[3][1][1])
|
229
|
+
|
230
|
+
@nested = Sexp.new(:lvar, formal_args[1])
|
231
|
+
|
232
|
+
process block
|
233
|
+
|
234
|
+
@prefix.pop
|
235
|
+
end
|
236
|
+
|
237
|
+
# map.something_abnormal '/blah', :controller => 'something', :action => 'wohoo'
|
238
|
+
def process_named_route exp
|
239
|
+
process_connect exp
|
240
|
+
end
|
241
|
+
|
242
|
+
#Process collection option
|
243
|
+
# :collection => { :some_action => :http_actions }
|
244
|
+
def process_collection exp
|
245
|
+
return unless exp.node_type == :hash
|
246
|
+
routes = @tracker.routes[@current_controller]
|
247
|
+
|
248
|
+
hash_iterate(exp) do |action, type|
|
249
|
+
routes << action[1]
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
private
|
254
|
+
|
255
|
+
#Checks an argument list for a hash that has a key :controller.
|
256
|
+
#If it does, returns the value.
|
257
|
+
#
|
258
|
+
#Otherwise, returns nil.
|
259
|
+
def check_for_controller_name args
|
260
|
+
args.each do |a|
|
261
|
+
if hash? a
|
262
|
+
hash_iterate(a) do |k, v|
|
263
|
+
if k[1] == :controller
|
264
|
+
return v[1]
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
nil
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
#This is for a really specific case where a hash is used as arguments
|
275
|
+
#to one of the map methods.
|
276
|
+
class RouteAliasProcessor < AliasProcessor
|
277
|
+
|
278
|
+
#This replaces
|
279
|
+
# { :some => :hash }.keys
|
280
|
+
#with
|
281
|
+
# [:some]
|
282
|
+
def process_call exp
|
283
|
+
process_default exp
|
284
|
+
|
285
|
+
if hash? exp[1] and exp[2] == :keys
|
286
|
+
keys = get_keys exp[1]
|
287
|
+
exp.clear
|
288
|
+
keys.each_with_index do |e,i|
|
289
|
+
exp[i] = e
|
290
|
+
end
|
291
|
+
end
|
292
|
+
exp
|
293
|
+
end
|
294
|
+
|
295
|
+
#Returns an array Sexp containing the keys from the hash
|
296
|
+
def get_keys hash
|
297
|
+
keys = Sexp.new(:array)
|
298
|
+
hash_iterate(hash) do |key, value|
|
299
|
+
keys << key
|
300
|
+
end
|
301
|
+
|
302
|
+
keys
|
303
|
+
end
|
304
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
#Processes the Sexp from routes.rb. Stores results in tracker.routes.
|
2
|
+
#
|
3
|
+
#Note that it is only interested in determining what methods on which
|
4
|
+
#controllers are used as routes, not the generated URLs for routes.
|
5
|
+
class RoutesProcessor < BaseProcessor
|
6
|
+
include RouteHelper
|
7
|
+
|
8
|
+
attr_reader :map, :nested, :current_controller
|
9
|
+
|
10
|
+
def initialize tracker
|
11
|
+
super
|
12
|
+
@map = Sexp.new(:lvar, :map)
|
13
|
+
@nested = nil #used for identifying nested targets
|
14
|
+
@prefix = [] #Controller name prefix (a module name, usually)
|
15
|
+
@current_controller = nil
|
16
|
+
@with_options = nil #For use inside map.with_options
|
17
|
+
end
|
18
|
+
|
19
|
+
def process_routes exp
|
20
|
+
process exp.dup
|
21
|
+
end
|
22
|
+
|
23
|
+
def process_call exp
|
24
|
+
case exp[2]
|
25
|
+
when :resources
|
26
|
+
process_resources exp
|
27
|
+
when :resource
|
28
|
+
process_resource exp
|
29
|
+
when :root
|
30
|
+
process_root exp
|
31
|
+
when :member
|
32
|
+
process_default exp
|
33
|
+
when :get, :put, :post, :delete
|
34
|
+
process_verb exp
|
35
|
+
when :match
|
36
|
+
process_match exp
|
37
|
+
else
|
38
|
+
exp
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_iter exp
|
43
|
+
case exp[1][2]
|
44
|
+
when :namespace
|
45
|
+
process_namespace exp
|
46
|
+
when :resource
|
47
|
+
process_resource_block exp
|
48
|
+
when :resources
|
49
|
+
process_resources_block exp
|
50
|
+
when :scope
|
51
|
+
process_scope_block exp
|
52
|
+
else
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def process_namespace exp
|
58
|
+
name = exp[1][3][1][1]
|
59
|
+
block = exp[3]
|
60
|
+
|
61
|
+
@prefix << camelize(name)
|
62
|
+
|
63
|
+
process block
|
64
|
+
|
65
|
+
@prefix.pop
|
66
|
+
|
67
|
+
exp
|
68
|
+
end
|
69
|
+
|
70
|
+
def process_root exp
|
71
|
+
args = exp[3][1..-1]
|
72
|
+
|
73
|
+
hash_iterate args[0] do |k, v|
|
74
|
+
if symbol? k and k[1] == :to
|
75
|
+
controller, action = extract_action v[1]
|
76
|
+
|
77
|
+
self.current_controller = controller
|
78
|
+
@tracker.routes[@current_controller] << action.to_sym
|
79
|
+
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
exp
|
85
|
+
end
|
86
|
+
|
87
|
+
def process_match exp
|
88
|
+
args = exp[3][1..-1]
|
89
|
+
|
90
|
+
hash_iterate args[0] do |k, v|
|
91
|
+
if string? k and string? v
|
92
|
+
controller, action = extract_action v[1]
|
93
|
+
|
94
|
+
self.current_controller = controller
|
95
|
+
@tracker.routes[@current_controller] << action.to_sym if action
|
96
|
+
elsif symbol? k and k[1] == :action
|
97
|
+
@tracker.routes[@current_controller] << v[1].to_sym
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
exp
|
102
|
+
end
|
103
|
+
|
104
|
+
def process_verb exp
|
105
|
+
args = exp[3][1..-1]
|
106
|
+
|
107
|
+
if symbol? args[0]
|
108
|
+
@tracker.routes[@current_controller] << args[0][1]
|
109
|
+
elsif string? args[0]
|
110
|
+
route = args[0][1].split "/"
|
111
|
+
if route.length != 2
|
112
|
+
@tracker.routes[@current_controller] << route[0].to_sym
|
113
|
+
else
|
114
|
+
self.current_controller = route[0]
|
115
|
+
@tracker.routes[@current_controller] << route[1].to_sym
|
116
|
+
@current_controller = nil
|
117
|
+
end
|
118
|
+
else hash? args[0]
|
119
|
+
hash_iterate args[0] do |k, v|
|
120
|
+
if string? v
|
121
|
+
controller, action = extract_action v[1]
|
122
|
+
|
123
|
+
self.current_controller = controller
|
124
|
+
@tracker.routes[@current_controller] << action.to_sym
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
exp
|
130
|
+
end
|
131
|
+
|
132
|
+
def process_resources exp
|
133
|
+
if exp[3] and exp[3][2] and exp[3][2][0] == :hash
|
134
|
+
#handle hash
|
135
|
+
elsif exp[3][1..-1].all? { |s| symbol? s }
|
136
|
+
exp[3][1..-1].each do |s|
|
137
|
+
self.current_controller = s[1]
|
138
|
+
add_resources_routes
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
exp
|
143
|
+
end
|
144
|
+
|
145
|
+
def process_resource exp
|
146
|
+
exp[3][1..-1].each do |s|
|
147
|
+
self.current_controller = s[1]
|
148
|
+
add_resource_routes
|
149
|
+
end
|
150
|
+
|
151
|
+
exp
|
152
|
+
end
|
153
|
+
|
154
|
+
def process_resources_block exp
|
155
|
+
process_resources exp[1]
|
156
|
+
process exp[3]
|
157
|
+
end
|
158
|
+
|
159
|
+
def process_resource_block exp
|
160
|
+
process_resource exp[1]
|
161
|
+
process exp[3]
|
162
|
+
end
|
163
|
+
|
164
|
+
def process_scope_block exp
|
165
|
+
#How to deal with options?
|
166
|
+
process exp[3]
|
167
|
+
end
|
168
|
+
|
169
|
+
def extract_action str
|
170
|
+
str.split "#"
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RouteHelper
|
2
|
+
#Manage Controller prefixes
|
3
|
+
#@prefix is an Array, but this method returns a string
|
4
|
+
#suitable for prefixing onto a controller name.
|
5
|
+
def prefix
|
6
|
+
if @prefix.length > 0
|
7
|
+
@prefix.join("::") << "::"
|
8
|
+
else
|
9
|
+
''
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
#Sets the controller name to a proper class name.
|
14
|
+
#For example
|
15
|
+
# self.current_controller = :session
|
16
|
+
# @controller == :SessionController #true
|
17
|
+
#
|
18
|
+
#Also prepends the prefix if there is one set.
|
19
|
+
def current_controller= name
|
20
|
+
@current_controller = (prefix + camelize(name) + "Controller").to_sym
|
21
|
+
@tracker.routes[@current_controller] ||= Set.new
|
22
|
+
end
|
23
|
+
|
24
|
+
#Add default routes
|
25
|
+
def add_resources_routes
|
26
|
+
@tracker.routes[@current_controller].merge [:index, :new, :create, :show, :edit, :update, :destroy]
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
#Add default routes minus :index
|
31
|
+
def add_resource_routes
|
32
|
+
@tracker.routes[@current_controller].merge [:new, :create, :show, :edit, :update, :destroy]
|
33
|
+
end
|
34
|
+
end
|
@@ -1,338 +1,11 @@
|
|
1
1
|
require 'processors/base_processor'
|
2
2
|
require 'processors/alias_processor'
|
3
|
+
require 'processors/lib/route_helper'
|
3
4
|
require 'util'
|
4
5
|
require 'set'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
class RoutesProcessor < BaseProcessor
|
11
|
-
attr_reader :map, :nested, :current_controller
|
12
|
-
|
13
|
-
def initialize tracker
|
14
|
-
super
|
15
|
-
@map = Sexp.new(:lvar, :map)
|
16
|
-
@nested = nil #used for identifying nested targets
|
17
|
-
@prefix = [] #Controller name prefix (a module name, usually)
|
18
|
-
@current_controller = nil
|
19
|
-
@with_options = nil #For use inside map.with_options
|
20
|
-
end
|
21
|
-
|
22
|
-
#Call this with parsed route file information.
|
23
|
-
#
|
24
|
-
#This method first calls RouteAliasProcessor#process_safely on the +exp+,
|
25
|
-
#so it does not modify the +exp+.
|
26
|
-
def process_routes exp
|
27
|
-
process RouteAliasProcessor.new.process_safely(exp)
|
28
|
-
end
|
29
|
-
|
30
|
-
#Looking for mapping of routes
|
31
|
-
def process_call exp
|
32
|
-
target = exp[1]
|
33
|
-
|
34
|
-
if target == map or target == nested
|
35
|
-
process_map exp
|
36
|
-
|
37
|
-
else
|
38
|
-
process_default exp
|
39
|
-
end
|
40
|
-
|
41
|
-
exp
|
42
|
-
end
|
43
|
-
|
44
|
-
#Process a map.something call
|
45
|
-
#based on the method used
|
46
|
-
def process_map exp
|
47
|
-
args = exp[3][1..-1]
|
48
|
-
|
49
|
-
case exp[2]
|
50
|
-
when :resource
|
51
|
-
process_resource args
|
52
|
-
when :resources
|
53
|
-
process_resources args
|
54
|
-
when :connect, :root
|
55
|
-
process_connect args
|
56
|
-
else
|
57
|
-
process_named_route args
|
58
|
-
end
|
59
|
-
|
60
|
-
exp
|
61
|
-
end
|
62
|
-
|
63
|
-
#Look for map calls that take a block.
|
64
|
-
#Otherwise, just do the default processing.
|
65
|
-
def process_iter exp
|
66
|
-
if exp[1][1] == map or exp[1][1] == nested
|
67
|
-
method = exp[1][2]
|
68
|
-
case method
|
69
|
-
when :namespace
|
70
|
-
process_namespace exp
|
71
|
-
when :resources, :resource
|
72
|
-
process_resources exp[1][3][1..-1]
|
73
|
-
process_default exp[3]
|
74
|
-
when :with_options
|
75
|
-
process_with_options exp
|
76
|
-
end
|
77
|
-
exp
|
78
|
-
else
|
79
|
-
super
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
#Process
|
84
|
-
# map.resources :x, :controller => :y, :member => ...
|
85
|
-
#etc.
|
86
|
-
def process_resources exp
|
87
|
-
controller = check_for_controller_name exp
|
88
|
-
if controller
|
89
|
-
self.current_controller = controller
|
90
|
-
process_resource_options exp[-1]
|
91
|
-
else
|
92
|
-
exp.each do |argument|
|
93
|
-
if sexp? argument and argument.node_type == :lit
|
94
|
-
self.current_controller = exp[0][1]
|
95
|
-
add_resources_routes
|
96
|
-
process_resource_options exp[-1]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
#Add default routes
|
103
|
-
def add_resources_routes
|
104
|
-
@tracker.routes[@current_controller].merge [:index, :new, :create, :show, :edit, :update, :destroy]
|
105
|
-
end
|
106
|
-
|
107
|
-
#Process all the options that might be in the hash passed to
|
108
|
-
#map.resource, et al.
|
109
|
-
def process_resource_options exp
|
110
|
-
if exp.nil? and @with_options
|
111
|
-
exp = @with_options
|
112
|
-
elsif @with_options
|
113
|
-
exp = exp.concat @with_options[1..-1]
|
114
|
-
end
|
115
|
-
return unless exp.node_type == :hash
|
116
|
-
|
117
|
-
hash_iterate(exp) do |option, value|
|
118
|
-
case option[1]
|
119
|
-
when :controller, :requirements, :singular, :path_prefix, :as,
|
120
|
-
:path_names, :shallow, :name_prefix
|
121
|
-
#should be able to skip
|
122
|
-
when :collection, :member, :new
|
123
|
-
process_collection value
|
124
|
-
when :has_one
|
125
|
-
save_controller = current_controller
|
126
|
-
process_resource value[1..-1]
|
127
|
-
self.current_controller = save_controller
|
128
|
-
when :has_many
|
129
|
-
save_controller = current_controller
|
130
|
-
process_resources value[1..-1]
|
131
|
-
self.current_controller = save_controller
|
132
|
-
when :only
|
133
|
-
process_option_only value
|
134
|
-
when :except
|
135
|
-
process_option_except value
|
136
|
-
else
|
137
|
-
raise "Unhandled resource option: #{option}"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
#Process route option :only => ...
|
143
|
-
def process_option_only exp
|
144
|
-
routes = @tracker.routes[@current_controller]
|
145
|
-
[:index, :new, :create, :show, :edit, :update, :destroy].each do |r|
|
146
|
-
routes.delete r
|
147
|
-
end
|
148
|
-
|
149
|
-
if exp.node_type == :array
|
150
|
-
exp[1..-1].each do |e|
|
151
|
-
routes << e[1]
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
#Process route option :except => ...
|
157
|
-
def process_option_except exp
|
158
|
-
return unless exp.node_type == :array
|
159
|
-
routes = @tracker.routes[@current_controller]
|
160
|
-
|
161
|
-
exp[1..-1].each do |e|
|
162
|
-
routes.delete e[1]
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
# map.resource :x, ..
|
167
|
-
def process_resource exp
|
168
|
-
controller = check_for_controller_name exp
|
169
|
-
if controller
|
170
|
-
self.current_controller = controller
|
171
|
-
process_resource_options exp[-1]
|
172
|
-
else
|
173
|
-
exp.each do |argument|
|
174
|
-
if argument.node_type == :lit
|
175
|
-
self.current_controller = pluralize(exp[0][1].to_s)
|
176
|
-
add_resource_routes
|
177
|
-
process_resource_options exp[-1]
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
#Add default routes minus :index
|
184
|
-
def add_resource_routes
|
185
|
-
@tracker.routes[@current_controller].merge [:new, :create, :show, :edit, :update, :destroy]
|
186
|
-
end
|
187
|
-
|
188
|
-
#Process
|
189
|
-
# map.connect '/something', :controller => 'blah', :action => 'whatever'
|
190
|
-
def process_connect exp
|
191
|
-
controller = check_for_controller_name exp
|
192
|
-
self.current_controller = controller if controller
|
193
|
-
|
194
|
-
#Check for default route
|
195
|
-
if string? exp[0]
|
196
|
-
if exp[0][1] == ":controller/:action/:id"
|
197
|
-
@tracker.routes[:allow_all_actions] = exp[0]
|
198
|
-
elsif exp[0][1].include? ":action"
|
199
|
-
@tracker.routes[@current_controller] = :allow_all_actions
|
200
|
-
return
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
#This -seems- redundant, but people might connect actions
|
205
|
-
#to a controller which already allows them all
|
206
|
-
return if @tracker.routes[@current_controller] == :allow_all_actions
|
207
|
-
|
208
|
-
exp[-1].each_with_index do |e,i|
|
209
|
-
if symbol? e and e[1] == :action
|
210
|
-
@tracker.routes[@current_controller] << exp[-1][i + 1][1].to_sym
|
211
|
-
return
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
# map.with_options :controller => 'something' do |something|
|
217
|
-
# something.resources :blah
|
218
|
-
# end
|
219
|
-
def process_with_options exp
|
220
|
-
@with_options = exp[1][3][-1]
|
221
|
-
@nested = Sexp.new(:lvar, exp[2][1])
|
222
|
-
|
223
|
-
self.current_controller = check_for_controller_name exp[1][3]
|
224
|
-
|
225
|
-
#process block
|
226
|
-
process exp[3]
|
227
|
-
|
228
|
-
@with_options = nil
|
229
|
-
@nested = nil
|
230
|
-
end
|
231
|
-
|
232
|
-
# map.namespace :something do |something|
|
233
|
-
# something.resources :blah
|
234
|
-
# end
|
235
|
-
def process_namespace exp
|
236
|
-
call = exp[1]
|
237
|
-
formal_args = exp[2]
|
238
|
-
block = exp[3]
|
239
|
-
|
240
|
-
@prefix << camelize(call[3][1][1])
|
241
|
-
|
242
|
-
@nested = Sexp.new(:lvar, formal_args[1])
|
243
|
-
|
244
|
-
process block
|
245
|
-
|
246
|
-
@prefix.pop
|
247
|
-
end
|
248
|
-
|
249
|
-
# map.something_abnormal '/blah', :controller => 'something', :action => 'wohoo'
|
250
|
-
def process_named_route exp
|
251
|
-
process_connect exp
|
252
|
-
end
|
253
|
-
|
254
|
-
#Process collection option
|
255
|
-
# :collection => { :some_action => :http_actions }
|
256
|
-
def process_collection exp
|
257
|
-
return unless exp.node_type == :hash
|
258
|
-
routes = @tracker.routes[@current_controller]
|
259
|
-
|
260
|
-
hash_iterate(exp) do |action, type|
|
261
|
-
routes << action[1]
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
#Manage Controller prefixes
|
266
|
-
#@prefix is an Array, but this method returns a string
|
267
|
-
#suitable for prefixing onto a controller name.
|
268
|
-
def prefix
|
269
|
-
if @prefix.length > 0
|
270
|
-
@prefix.join("::") << "::"
|
271
|
-
else
|
272
|
-
''
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
#Sets the controller name to a proper class name.
|
277
|
-
#For example
|
278
|
-
# self.current_controller = :session
|
279
|
-
# @controller == :SessionController #true
|
280
|
-
#
|
281
|
-
#Also prepends the prefix if there is one set.
|
282
|
-
def current_controller= name
|
283
|
-
@current_controller = (prefix + camelize(name) + "Controller").to_sym
|
284
|
-
@tracker.routes[@current_controller] ||= Set.new
|
285
|
-
end
|
286
|
-
|
287
|
-
private
|
288
|
-
|
289
|
-
#Checks an argument list for a hash that has a key :controller.
|
290
|
-
#If it does, returns the value.
|
291
|
-
#
|
292
|
-
#Otherwise, returns nil.
|
293
|
-
def check_for_controller_name args
|
294
|
-
args.each do |a|
|
295
|
-
if hash? a
|
296
|
-
hash_iterate(a) do |k, v|
|
297
|
-
if k[1] == :controller
|
298
|
-
return v[1]
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
|
-
nil
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
#This is for a really specific case where a hash is used as arguments
|
309
|
-
#to one of the map methods.
|
310
|
-
class RouteAliasProcessor < AliasProcessor
|
311
|
-
|
312
|
-
#This replaces
|
313
|
-
# { :some => :hash }.keys
|
314
|
-
#with
|
315
|
-
# [:some]
|
316
|
-
def process_call exp
|
317
|
-
process_default exp
|
318
|
-
|
319
|
-
if hash? exp[1] and exp[2] == :keys
|
320
|
-
keys = get_keys exp[1]
|
321
|
-
exp.clear
|
322
|
-
keys.each_with_index do |e,i|
|
323
|
-
exp[i] = e
|
324
|
-
end
|
325
|
-
end
|
326
|
-
exp
|
327
|
-
end
|
328
|
-
|
329
|
-
#Returns an array Sexp containing the keys from the hash
|
330
|
-
def get_keys hash
|
331
|
-
keys = Sexp.new(:array)
|
332
|
-
hash_iterate(hash) do |key, value|
|
333
|
-
keys << key
|
334
|
-
end
|
335
|
-
|
336
|
-
keys
|
337
|
-
end
|
7
|
+
if OPTIONS[:rails3]
|
8
|
+
require 'processors/lib/rails3_route_processor'
|
9
|
+
else
|
10
|
+
require 'processors/lib/rails2_route_processor'
|
338
11
|
end
|
data/lib/report.rb
CHANGED
@@ -631,7 +631,9 @@ class Report
|
|
631
631
|
[:model_warnings, "Model"], [:template_warnings, "Template"]].map do |meth, category|
|
632
632
|
|
633
633
|
checks.send(meth).map do |w|
|
634
|
-
|
634
|
+
line = w.line || 0
|
635
|
+
w.warning_type.gsub! /[^\w\s]/, ' '
|
636
|
+
"#{file_for w}\t#{line}\t#{w.warning_type}\t#{category}\t#{w.format_message}\t#{TEXT_CONFIDENCE[w.confidence]}"
|
635
637
|
end.join "\n"
|
636
638
|
|
637
639
|
end.join "\n"
|
data/lib/scanner.rb
CHANGED
data/lib/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Version = "0.3.
|
1
|
+
Version = "0.3.1"
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brakeman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 17
|
5
|
+
prerelease:
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Justin Collins
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2011-03
|
18
|
+
date: 2011-05-03 00:00:00 -07:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
@@ -25,6 +26,7 @@ dependencies:
|
|
25
26
|
requirements:
|
26
27
|
- - ~>
|
27
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
28
30
|
segments:
|
29
31
|
- 2
|
30
32
|
- 2
|
@@ -39,6 +41,7 @@ dependencies:
|
|
39
41
|
requirements:
|
40
42
|
- - ~>
|
41
43
|
- !ruby/object:Gem::Version
|
44
|
+
hash: 23
|
42
45
|
segments:
|
43
46
|
- 1
|
44
47
|
- 2
|
@@ -54,6 +57,7 @@ dependencies:
|
|
54
57
|
requirements:
|
55
58
|
- - ~>
|
56
59
|
- !ruby/object:Gem::Version
|
60
|
+
hash: 9
|
57
61
|
segments:
|
58
62
|
- 1
|
59
63
|
- 6
|
@@ -69,6 +73,7 @@ dependencies:
|
|
69
73
|
requirements:
|
70
74
|
- - ~>
|
71
75
|
- !ruby/object:Gem::Version
|
76
|
+
hash: 29
|
72
77
|
segments:
|
73
78
|
- 2
|
74
79
|
- 6
|
@@ -84,6 +89,7 @@ dependencies:
|
|
84
89
|
requirements:
|
85
90
|
- - ~>
|
86
91
|
- !ruby/object:Gem::Version
|
92
|
+
hash: 31
|
87
93
|
segments:
|
88
94
|
- 3
|
89
95
|
- 0
|
@@ -104,50 +110,53 @@ files:
|
|
104
110
|
- WARNING_TYPES
|
105
111
|
- FEATURES
|
106
112
|
- README.md
|
107
|
-
- lib/
|
108
|
-
- lib/processors/alias_processor.rb
|
109
|
-
- lib/processors/haml_template_processor.rb
|
110
|
-
- lib/processors/output_processor.rb
|
113
|
+
- lib/warning.rb
|
111
114
|
- lib/processors/params_processor.rb
|
112
|
-
- lib/processors/erubis_template_processor.rb
|
113
115
|
- lib/processors/controller_alias_processor.rb
|
114
|
-
- lib/processors/
|
115
|
-
- lib/processors/
|
116
|
-
- lib/processors/
|
117
|
-
- lib/processors/lib/find_call.rb
|
118
|
-
- lib/processors/route_processor.rb
|
119
|
-
- lib/processors/model_processor.rb
|
116
|
+
- lib/processors/base_processor.rb
|
117
|
+
- lib/processors/controller_processor.rb
|
118
|
+
- lib/processors/library_processor.rb
|
120
119
|
- lib/processors/erb_template_processor.rb
|
120
|
+
- lib/processors/haml_template_processor.rb
|
121
121
|
- lib/processors/template_alias_processor.rb
|
122
|
+
- lib/processors/route_processor.rb
|
123
|
+
- lib/processors/model_processor.rb
|
124
|
+
- lib/processors/lib/find_call.rb
|
125
|
+
- lib/processors/lib/processor_helper.rb
|
126
|
+
- lib/processors/lib/rails3_route_processor.rb
|
127
|
+
- lib/processors/lib/route_helper.rb
|
128
|
+
- lib/processors/lib/rails2_route_processor.rb
|
129
|
+
- lib/processors/lib/find_model_call.rb
|
130
|
+
- lib/processors/lib/render_helper.rb
|
131
|
+
- lib/processors/alias_processor.rb
|
132
|
+
- lib/processors/output_processor.rb
|
122
133
|
- lib/processors/config_processor.rb
|
134
|
+
- lib/processors/erubis_template_processor.rb
|
123
135
|
- lib/processors/template_processor.rb
|
124
|
-
- lib/processors/controller_processor.rb
|
125
|
-
- lib/processors/library_processor.rb
|
126
|
-
- lib/report.rb
|
127
|
-
- lib/util.rb
|
128
136
|
- lib/checks/check_send_file.rb
|
129
|
-
- lib/checks/
|
130
|
-
- lib/checks/
|
131
|
-
- lib/checks/check_execute.rb
|
132
|
-
- lib/checks/check_mass_assignment.rb
|
137
|
+
- lib/checks/check_session_settings.rb
|
138
|
+
- lib/checks/check_nested_attributes.rb
|
133
139
|
- lib/checks/check_sql.rb
|
134
|
-
- lib/checks/
|
135
|
-
- lib/checks/check_validation_regex.rb
|
140
|
+
- lib/checks/check_mass_assignment.rb
|
136
141
|
- lib/checks/check_cross_site_scripting.rb
|
137
|
-
- lib/checks/check_redirect.rb
|
138
|
-
- lib/checks/check_session_settings.rb
|
139
|
-
- lib/checks/check_forgery_setting.rb
|
140
|
-
- lib/checks/base_check.rb
|
141
142
|
- lib/checks/check_model_attributes.rb
|
142
|
-
- lib/checks/
|
143
|
+
- lib/checks/check_default_routes.rb
|
143
144
|
- lib/checks/check_evaluation.rb
|
145
|
+
- lib/checks/check_validation_regex.rb
|
146
|
+
- lib/checks/check_execute.rb
|
147
|
+
- lib/checks/check_mail_to.rb
|
148
|
+
- lib/checks/base_check.rb
|
144
149
|
- lib/checks/check_file_access.rb
|
145
|
-
- lib/
|
146
|
-
- lib/
|
150
|
+
- lib/checks/check_redirect.rb
|
151
|
+
- lib/checks/check_forgery_setting.rb
|
152
|
+
- lib/checks/check_render.rb
|
147
153
|
- lib/tracker.rb
|
148
|
-
- lib/
|
154
|
+
- lib/util.rb
|
155
|
+
- lib/report.rb
|
149
156
|
- lib/version.rb
|
150
|
-
- lib/
|
157
|
+
- lib/scanner.rb
|
158
|
+
- lib/checks.rb
|
159
|
+
- lib/processor.rb
|
151
160
|
- lib/format/style.css
|
152
161
|
has_rdoc: true
|
153
162
|
homepage: http://github.com/presidentbeef/brakeman
|
@@ -163,6 +172,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
172
|
requirements:
|
164
173
|
- - ">="
|
165
174
|
- !ruby/object:Gem::Version
|
175
|
+
hash: 3
|
166
176
|
segments:
|
167
177
|
- 0
|
168
178
|
version: "0"
|
@@ -171,13 +181,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
181
|
requirements:
|
172
182
|
- - ">="
|
173
183
|
- !ruby/object:Gem::Version
|
184
|
+
hash: 3
|
174
185
|
segments:
|
175
186
|
- 0
|
176
187
|
version: "0"
|
177
188
|
requirements: []
|
178
189
|
|
179
190
|
rubyforge_project:
|
180
|
-
rubygems_version: 1.
|
191
|
+
rubygems_version: 1.4.1
|
181
192
|
signing_key:
|
182
193
|
specification_version: 3
|
183
194
|
summary: Security vulnerability scanner for Ruby on Rails.
|