@@ -396,8 +396,8 class ApplicationController < ActionController::Base | |||||
396 |
|
396 | |||
397 | def redirect_back_or_default(default, options={}) |
|
397 | def redirect_back_or_default(default, options={}) | |
398 | back_url = params[:back_url].to_s |
|
398 | back_url = params[:back_url].to_s | |
399 |
if back_url.present? && valid_back_url |
|
399 | if back_url.present? && valid_url = validate_back_url(back_url) | |
400 |
redirect_to( |
|
400 | redirect_to(valid_url) | |
401 | return |
|
401 | return | |
402 | elsif options[:referer] |
|
402 | elsif options[:referer] | |
403 | redirect_to_referer_or default |
|
403 | redirect_to_referer_or default | |
@@ -407,8 +407,9 class ApplicationController < ActionController::Base | |||||
407 | false |
|
407 | false | |
408 | end |
|
408 | end | |
409 |
|
409 | |||
410 |
# Returns t |
|
410 | # Returns a validated URL string if back_url is a valid url for redirection, | |
411 | def valid_back_url?(back_url) |
|
411 | # otherwise false | |
|
412 | def validate_back_url(back_url) | |||
412 | if CGI.unescape(back_url).include?('..') |
|
413 | if CGI.unescape(back_url).include?('..') | |
413 | return false |
|
414 | return false | |
414 | end |
|
415 | end | |
@@ -419,19 +420,36 class ApplicationController < ActionController::Base | |||||
419 | return false |
|
420 | return false | |
420 | end |
|
421 | end | |
421 |
|
422 | |||
422 | if uri.host.present? && uri.host != request.host |
|
423 | [:scheme, :host, :port].each do |component| | |
|
424 | if uri.send(component).present? && uri.send(component) != request.send(component) | |||
|
425 | return false | |||
|
426 | end | |||
|
427 | uri.send(:"#{component}=", nil) | |||
|
428 | end | |||
|
429 | # Always ignore basic user:password in the URL | |||
|
430 | uri.userinfo = nil | |||
|
431 | ||||
|
432 | path = uri.to_s | |||
|
433 | # Ensure that the remaining URL starts with a slash, followed by a | |||
|
434 | # non-slash character or the end | |||
|
435 | if path !~ %r{\A/([^/]|\z)} | |||
423 | return false |
|
436 | return false | |
424 | end |
|
437 | end | |
425 |
|
438 | |||
426 |
if |
|
439 | if path.match(%r{/(login|account/register)}) | |
427 | return false |
|
440 | return false | |
428 | end |
|
441 | end | |
429 |
|
442 | |||
430 |
if relative_url_root.present? && ! |
|
443 | if relative_url_root.present? && !path.starts_with?(relative_url_root) | |
431 | return false |
|
444 | return false | |
432 | end |
|
445 | end | |
433 |
|
446 | |||
434 |
return |
|
447 | return path | |
|
448 | end | |||
|
449 | private :validate_back_url | |||
|
450 | ||||
|
451 | def valid_back_url?(back_url) | |||
|
452 | !!validate_back_url(back_url) | |||
435 | end |
|
453 | end | |
436 | private :valid_back_url? |
|
454 | private :valid_back_url? | |
437 |
|
455 |
@@ -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