@@ -396,8 +396,8 class ApplicationController < ActionController::Base | |||
|
396 | 396 | |
|
397 | 397 | def redirect_back_or_default(default, options={}) |
|
398 | 398 | back_url = params[:back_url].to_s |
|
399 |
if back_url.present? && valid_back_url |
|
|
400 |
redirect_to( |
|
|
399 | if back_url.present? && valid_url = validate_back_url(back_url) | |
|
400 | redirect_to(valid_url) | |
|
401 | 401 | return |
|
402 | 402 | elsif options[:referer] |
|
403 | 403 | redirect_to_referer_or default |
@@ -407,8 +407,9 class ApplicationController < ActionController::Base | |||
|
407 | 407 | false |
|
408 | 408 | end |
|
409 | 409 | |
|
410 |
# Returns t |
|
|
411 | def valid_back_url?(back_url) | |
|
410 | # Returns a validated URL string if back_url is a valid url for redirection, | |
|
411 | # otherwise false | |
|
412 | def validate_back_url(back_url) | |
|
412 | 413 | if CGI.unescape(back_url).include?('..') |
|
413 | 414 | return false |
|
414 | 415 | end |
@@ -419,19 +420,36 class ApplicationController < ActionController::Base | |||
|
419 | 420 | return false |
|
420 | 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 | 436 | return false |
|
424 | 437 | end |
|
425 | 438 | |
|
426 |
if |
|
|
439 | if path.match(%r{/(login|account/register)}) | |
|
427 | 440 | return false |
|
428 | 441 | end |
|
429 | 442 | |
|
430 |
if relative_url_root.present? && ! |
|
|
443 | if relative_url_root.present? && !path.starts_with?(relative_url_root) | |
|
431 | 444 | return false |
|
432 | 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 | 453 | end |
|
436 | 454 | private :valid_back_url? |
|
437 | 455 |
@@ -63,6 +63,7 class AccountControllerTest < ActionController::TestCase | |||
|
63 | 63 | # request.uri is "test.host" in test environment |
|
64 | 64 | back_urls = [ |
|
65 | 65 | 'http://test.host/issues/show/1', |
|
66 | 'http://test.host/', | |
|
66 | 67 | '/' |
|
67 | 68 | ] |
|
68 | 69 | back_urls.each do |back_url| |
@@ -108,7 +109,16 class AccountControllerTest < ActionController::TestCase | |||
|
108 | 109 | 'http://test.host/fake/issues', |
|
109 | 110 | 'http://test.host/redmine/../fake', |
|
110 | 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 | 123 | back_urls.each do |back_url| |
|
114 | 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