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