Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Rails 3 route processing #116

Merged
merged 11 commits into from Jul 25, 2012
116 changes: 93 additions & 23 deletions lib/brakeman/processors/lib/rails3_route_processor.rb
Expand Up @@ -14,6 +14,7 @@ def initialize tracker
@prefix = [] #Controller name prefix (a module name, usually) @prefix = [] #Controller name prefix (a module name, usually)
@current_controller = nil @current_controller = nil
@with_options = nil #For use inside map.with_options @with_options = nil #For use inside map.with_options
@controller_block = false
end end


def process_routes exp def process_routes exp
Expand Down Expand Up @@ -49,6 +50,8 @@ def process_iter exp
process_resources_block exp process_resources_block exp
when :scope when :scope
process_scope_block exp process_scope_block exp
when :controller
process_controller_block exp
else else
super super
end end
Expand All @@ -71,10 +74,8 @@ def process_root exp
args = exp[3][1..-1] args = exp[3][1..-1]


if value = hash_access(args[0], :to) if value = hash_access(args[0], :to)
if string? value[1] if string? value
controller, action = extract_action v[1] add_route_from_string value

add_route action, controller
end end
end end


Expand All @@ -96,18 +97,36 @@ def process_match exp
return exp return exp
elsif matcher.include? ':action' elsif matcher.include? ':action'
action_variable = true action_variable = true
elsif args[1].nil? and in_controller_block? and not matcher.include? ":"
add_route matcher
end end
end end


if hash? args[-1] if hash? args[-1]
hash_iterate args[-1] do |k, v| hash_iterate args[-1] do |k, v|
if string? k and string? v if string? k
controller, action = extract_action v[1] if string? v
add_route_from_string v[1]
elsif in_controller_block? and symbol? v
add_route v
end
elsif symbol? k
case k[1]
when :action
if string? v
add_route_from_string v
else
add_route v
end


add_route action if action
elsif symbol? k and k[1] == :action
add_route action
action_variable = false action_variable = false
when :to
if string? v
add_route_from_string v[1]
elsif in_controller_block? and symbol? v
add_route v
end
end
end end
end end
end end
Expand All @@ -116,20 +135,35 @@ def process_match exp
@tracker.routes[@current_controller] = :allow_all_actions @tracker.routes[@current_controller] = :allow_all_actions
end end


@current_controller = nil unless in_controller_block?
exp exp
end end


def add_route_from_string value
value = value[1] if string? value

controller, action = extract_action value

if action
add_route action, controller
elsif in_controller_block?
add_route value
end
end

def process_verb exp def process_verb exp
args = exp[3][1..-1] args = exp[3][1..-1]


if symbol? args[0] and not hash? args[1] if symbol? args[0] and not hash? args[1]
add_route args[0] add_route args[0]
elsif hash? args[1] elsif hash? args[1]
hash_iterate args[1] do |k, v| hash_iterate args[1] do |k, v|
if symbol? k and k[1] == :to and string? v if symbol? k and k[1] == :to
controller, action = extract_action v[1] if string? v

add_route_from_string v[1]
add_route action, controller elsif in_controller_block? and symbol? v
add_route v
end
end end
end end
elsif string? args[0] elsif string? args[0]
Expand All @@ -138,19 +172,22 @@ def process_verb exp
add_route route[0] add_route route[0]
else else
add_route route[1], route[0] add_route route[1], route[0]
@current_controller = nil
end end
elsif in_controller_block? and symbol? args[0]
add_route args[0]
else hash? args[0] else hash? args[0]
hash_iterate args[0] do |k, v| hash_iterate args[0] do |k, v|
if string? v if string? k
controller, action = extract_action v[1] if string? v

add_route_from_string v
add_route action, controller elsif in_controller_block?
break add_route v
end
end end
end end
end end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alias :process_resources_block, :process_resource_block?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are slightly different...



@current_controller = nil unless in_controller_block?
exp exp
end end


Expand All @@ -166,6 +203,7 @@ def process_resources exp
end end
end end


@current_controller = nil unless in_controller_block?
exp exp
end end


Expand All @@ -181,18 +219,27 @@ def process_resource exp
end end
end end


@current_controller = nil unless in_controller_block?
exp exp
end end


def process_resources_block exp def process_resources_block exp
process_resources exp[1] in_controller_block do
process exp[3] process_resources exp[1]
process exp[3]
end

@current_controller = nil
exp exp
end end


def process_resource_block exp def process_resource_block exp
process_resource exp[1] in_controller_block do
process exp[3] process_resource exp[1]
process exp[3]
end

@current_controller = nil
exp exp
end end


Expand All @@ -202,7 +249,30 @@ def process_scope_block exp
exp exp
end end


def process_controller_block exp
args = exp[1][3]
self.current_controller = args[1][1]

in_controller_block do
process exp[-1] if exp[-1]
end

@current_controller = nil
exp
end

def extract_action str def extract_action str
str.split "#" str.split "#"
end end

def in_controller_block?
@controller_block
end

def in_controller_block
prev_block = @controller_block
@controller_block = true
yield
@controller_block = prev_block
end
end end
6 changes: 5 additions & 1 deletion lib/brakeman/processors/lib/route_helper.rb
Expand Up @@ -35,7 +35,11 @@ def add_route route, controller = nil
self.current_controller = controller self.current_controller = controller
end end


@tracker.routes[@current_controller] << route routes = @tracker.routes[@current_controller]

if routes and routes != :allow_all_actions
routes << route
end
end end


#Add default routes #Add default routes
Expand Down
29 changes: 29 additions & 0 deletions test/apps/rails3.1/app/controllers/other_controller.rb
@@ -0,0 +1,29 @@
class OtherController < ApplicationController
def a
@a = params[:bad]
end

def b
@b = params[:bad]
end

def c
@c = params[:bad]
end

def d
@d = params[:bad]
end

def e
@e = params[:bad]
end

def f
@f = params[:bad]
end

def g
@g = params[:bad]
end
end
1 change: 1 addition & 0 deletions test/apps/rails3.1/app/views/other/a.html.erb
@@ -0,0 +1 @@
<%= raw @a %>
1 change: 1 addition & 0 deletions test/apps/rails3.1/app/views/other/b.html.erb
@@ -0,0 +1 @@
<%= raw @b %>
1 change: 1 addition & 0 deletions test/apps/rails3.1/app/views/other/c.html.erb
@@ -0,0 +1 @@
<%= raw @c %>
1 change: 1 addition & 0 deletions test/apps/rails3.1/app/views/other/d.html.erb
@@ -0,0 +1 @@
<%= raw @d %>
1 change: 1 addition & 0 deletions test/apps/rails3.1/app/views/other/e.html.erb
@@ -0,0 +1 @@
<%= raw @e %>
1 change: 1 addition & 0 deletions test/apps/rails3.1/app/views/other/f.html.erb
@@ -0,0 +1 @@
<%= raw @f %>
1 change: 1 addition & 0 deletions test/apps/rails3.1/app/views/other/g.html.erb
@@ -0,0 +1 @@
<%= raw @g %>
17 changes: 17 additions & 0 deletions test/apps/rails3.1/config/routes.rb
Expand Up @@ -4,6 +4,23 @@
get 'mixin_default' get 'mixin_default'
end end


resources :other do
get :a
delete 'f'
end

controller :other do
get 'b'
post 'something' => 'c'
put 'dee', :to => :d
end

match 'e', :to => 'other#e', :as => 'eeeee'

get 'g' => 'other#g'

match 'blah/:id', :action => 'blarg'

# The priority is based upon order of creation: # The priority is based upon order of creation:
# first created -> highest priority. # first created -> highest priority.


Expand Down
64 changes: 63 additions & 1 deletion test/tests/test_rails31.rb
Expand Up @@ -13,7 +13,7 @@ def report
def expected def expected
@expected ||= { @expected ||= {
:model => 0, :model => 0,
:template => 4, :template => 11,
:controller => 1, :controller => 1,
:warning => 44 } :warning => 44 }
end end
Expand Down Expand Up @@ -455,6 +455,68 @@ def test_controller_mixin_default_render
:file => /users\/mixin_default\.html\.erb/ :file => /users\/mixin_default\.html\.erb/
end end


def test_get_in_resources_block
assert_warning :type => :template,
:warning_type => "Cross Site Scripting",
:line => 1,
:message => /^Unescaped\ parameter\ value/,
:confidence => 0,
:file => /\/a\.html\.erb/
end

def test_get_in_controller_block
assert_warning :type => :template,
:warning_type => "Cross Site Scripting",
:line => 1,
:message => /^Unescaped\ parameter\ value/,
:confidence => 0,
:file => /\/b\.html\.erb/
end

def test_post_with_just_hash_in_controller_block
assert_warning :type => :template,
:warning_type => "Cross Site Scripting",
:line => 1,
:message => /^Unescaped\ parameter\ value/,
:confidence => 0,
:file => /\/c\.html\.erb/
end

def test_put_to_in_controller_block
assert_warning :type => :template,
:warning_type => "Cross Site Scripting",
:line => 1,
:message => /^Unescaped\ parameter\ value/,
:confidence => 0,
:file => /\/d\.html\.erb/
end

def test_match_to_route
assert_warning :type => :template,
:warning_type => "Cross Site Scripting",
:line => 1,
:message => /^Unescaped\ parameter\ value/,
:confidence => 0,
:file => /\/e\.html\.erb/
end

def test_delete_in_resources_block
assert_warning :type => :template,
:warning_type => "Cross Site Scripting",
:line => 1,
:message => /^Unescaped\ parameter\ value/,
:confidence => 0,
:file => /\/f\.html\.erb/
end

def test_route_hash_shorthand
assert_warning :type => :template,
:warning_type => "Cross Site Scripting",
:line => 1,
:message => /^Unescaped\ parameter\ value/,
:confidence => 0,
:file => /\/g\.html\.erb/
end


def test_file_access_indirect_user_input def test_file_access_indirect_user_input
assert_warning :type => :warning, assert_warning :type => :warning,
Expand Down