##// END OF EJS Templates
Don't redirect to another suburi (#16530)....
Jean-Philippe Lang -
r12938:0125ba14f6b0
parent child
Show More
@@ -376,18 +376,9 class ApplicationController < ActionController::Base
376
376
377 def redirect_back_or_default(default, options={})
377 def redirect_back_or_default(default, options={})
378 back_url = params[:back_url].to_s
378 back_url = params[:back_url].to_s
379 if back_url.present?
379 if back_url.present? && valid_back_url?(back_url)
380 begin
380 redirect_to(back_url)
381 uri = URI.parse(back_url)
381 return
382 # do not redirect user to another host or to the login or register page
383 if ((uri.relative? && back_url.match(%r{\A/(\w.*)?\z})) || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
384 redirect_to(back_url)
385 return
386 end
387 rescue URI::InvalidURIError
388 logger.warn("Could not redirect to invalid URL #{back_url}")
389 # redirect to default
390 end
391 elsif options[:referer]
382 elsif options[:referer]
392 redirect_to_referer_or default
383 redirect_to_referer_or default
393 return
384 return
@@ -396,6 +387,34 class ApplicationController < ActionController::Base
396 false
387 false
397 end
388 end
398
389
390 # Returns true if back_url is a valid url for redirection, otherwise false
391 def valid_back_url?(back_url)
392 if CGI.unescape(back_url).include?('..')
393 return false
394 end
395
396 begin
397 uri = URI.parse(back_url)
398 rescue URI::InvalidURIError
399 return false
400 end
401
402 if uri.host.present? && uri.host != request.host
403 return false
404 end
405
406 if uri.path.match(%r{/(login|account/register)})
407 return false
408 end
409
410 if relative_url_root.present? && !uri.path.starts_with?(relative_url_root)
411 return false
412 end
413
414 return true
415 end
416 private :valid_back_url?
417
399 # Redirects to the request referer if present, redirects to args or call block otherwise.
418 # Redirects to the request referer if present, redirects to args or call block otherwise.
400 def redirect_to_referer_or(*args, &block)
419 def redirect_to_referer_or(*args, &block)
401 redirect_to :back
420 redirect_to :back
@@ -71,6 +71,22 class AccountControllerTest < ActionController::TestCase
71 end
71 end
72 end
72 end
73
73
74 def test_login_with_suburi_should_redirect_to_back_url_param
75 @relative_url_root = ApplicationController.relative_url_root
76 ApplicationController.relative_url_root = '/redmine'
77
78 back_urls = [
79 'http://test.host/redmine/issues/show/1',
80 '/redmine'
81 ]
82 back_urls.each do |back_url|
83 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url
84 assert_redirected_to back_url
85 end
86 ensure
87 ApplicationController.relative_url_root = @relative_url_root
88 end
89
74 def test_login_should_not_redirect_to_another_host
90 def test_login_should_not_redirect_to_another_host
75 back_urls = [
91 back_urls = [
76 'http://test.foo/fake',
92 'http://test.foo/fake',
@@ -82,6 +98,26 class AccountControllerTest < ActionController::TestCase
82 end
98 end
83 end
99 end
84
100
101 def test_login_with_suburi_should_not_redirect_to_another_suburi
102 @relative_url_root = ApplicationController.relative_url_root
103 ApplicationController.relative_url_root = '/redmine'
104
105 back_urls = [
106 'http://test.host/',
107 'http://test.host/fake',
108 'http://test.host/fake/issues',
109 'http://test.host/redmine/../fake',
110 'http://test.host/redmine/../fake/issues',
111 'http://test.host/redmine/%2e%2e/fake'
112 ]
113 back_urls.each do |back_url|
114 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url
115 assert_redirected_to '/my/page'
116 end
117 ensure
118 ApplicationController.relative_url_root = @relative_url_root
119 end
120
85 def test_login_with_wrong_password
121 def test_login_with_wrong_password
86 post :login, :username => 'admin', :password => 'bad'
122 post :login, :username => 'admin', :password => 'bad'
87 assert_response :success
123 assert_response :success
General Comments 0
You need to be logged in to leave comments. Login now