@@ -390,8 +390,8 class ApplicationController < ActionController::Base | |||||
390 |
|
390 | |||
391 | def redirect_back_or_default(default, options={}) |
|
391 | def redirect_back_or_default(default, options={}) | |
392 | back_url = params[:back_url].to_s |
|
392 | back_url = params[:back_url].to_s | |
393 |
if back_url.present? && valid_back_url |
|
393 | if back_url.present? && valid_url = validate_back_url(back_url) | |
394 |
redirect_to( |
|
394 | redirect_to(valid_url) | |
395 | return |
|
395 | return | |
396 | elsif options[:referer] |
|
396 | elsif options[:referer] | |
397 | redirect_to_referer_or default |
|
397 | redirect_to_referer_or default | |
@@ -401,8 +401,9 class ApplicationController < ActionController::Base | |||||
401 | false |
|
401 | false | |
402 | end |
|
402 | end | |
403 |
|
403 | |||
404 |
# Returns t |
|
404 | # Returns a validated URL string if back_url is a valid url for redirection, | |
405 | def valid_back_url?(back_url) |
|
405 | # otherwise false | |
|
406 | def validate_back_url(back_url) | |||
406 | if CGI.unescape(back_url).include?('..') |
|
407 | if CGI.unescape(back_url).include?('..') | |
407 | return false |
|
408 | return false | |
408 | end |
|
409 | end | |
@@ -413,19 +414,36 class ApplicationController < ActionController::Base | |||||
413 | return false |
|
414 | return false | |
414 | end |
|
415 | end | |
415 |
|
416 | |||
416 | if uri.host.present? && uri.host != request.host |
|
417 | [:scheme, :host, :port].each do |component| | |
|
418 | if uri.send(component).present? && uri.send(component) != request.send(component) | |||
|
419 | return false | |||
|
420 | end | |||
|
421 | uri.send(:"#{component}=", nil) | |||
|
422 | end | |||
|
423 | # Always ignore basic user:password in the URL | |||
|
424 | uri.userinfo = nil | |||
|
425 | ||||
|
426 | path = uri.to_s | |||
|
427 | # Ensure that the remaining URL starts with a slash, followed by a | |||
|
428 | # non-slash character or the end | |||
|
429 | if path !~ %r{\A/([^/]|\z)} | |||
417 | return false |
|
430 | return false | |
418 | end |
|
431 | end | |
419 |
|
432 | |||
420 |
if |
|
433 | if path.match(%r{/(login|account/register)}) | |
421 | return false |
|
434 | return false | |
422 | end |
|
435 | end | |
423 |
|
436 | |||
424 |
if relative_url_root.present? && ! |
|
437 | if relative_url_root.present? && !path.starts_with?(relative_url_root) | |
425 | return false |
|
438 | return false | |
426 | end |
|
439 | end | |
427 |
|
440 | |||
428 |
return |
|
441 | return path | |
|
442 | end | |||
|
443 | private :validate_back_url | |||
|
444 | ||||
|
445 | def valid_back_url?(back_url) | |||
|
446 | !!validate_back_url(back_url) | |||
429 | end |
|
447 | end | |
430 | private :valid_back_url? |
|
448 | private :valid_back_url? | |
431 |
|
449 |
@@ -63,6 +63,7 class AccountControllerTest < ActionController::TestCase | |||||
63 | # request.uri is "test.host" in test environment |
|
63 | # request.uri is "test.host" in test environment | |
64 | back_urls = [ |
|
64 | back_urls = [ | |
65 | 'http://test.host/issues/show/1', |
|
65 | 'http://test.host/issues/show/1', | |
|
66 | 'http://test.host/', | |||
66 | '/' |
|
67 | '/' | |
67 | ] |
|
68 | ] | |
68 | back_urls.each do |back_url| |
|
69 | back_urls.each do |back_url| | |
@@ -108,7 +109,16 class AccountControllerTest < ActionController::TestCase | |||||
108 | 'http://test.host/fake/issues', |
|
109 | 'http://test.host/fake/issues', | |
109 | 'http://test.host/redmine/../fake', |
|
110 | 'http://test.host/redmine/../fake', | |
110 | 'http://test.host/redmine/../fake/issues', |
|
111 | 'http://test.host/redmine/../fake/issues', | |
111 | 'http://test.host/redmine/%2e%2e/fake' |
|
112 | 'http://test.host/redmine/%2e%2e/fake', | |
|
113 | '//test.foo/fake', | |||
|
114 | 'http://test.host//fake', | |||
|
115 | 'http://test.host/\n//fake', | |||
|
116 | '//bar@test.foo', | |||
|
117 | '//test.foo', | |||
|
118 | '////test.foo', | |||
|
119 | '@test.foo', | |||
|
120 | 'fake@test.foo', | |||
|
121 | '.test.foo' | |||
112 | ] |
|
122 | ] | |
113 | back_urls.each do |back_url| |
|
123 | back_urls.each do |back_url| | |
114 | post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url |
|
124 | post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url |
General Comments 0
You need to be logged in to leave comments.
Login now