@@ -393,8 +393,8 class ApplicationController < ActionController::Base | |||||
393 |
|
393 | |||
394 | def redirect_back_or_default(default, options={}) |
|
394 | def redirect_back_or_default(default, options={}) | |
395 | back_url = params[:back_url].to_s |
|
395 | back_url = params[:back_url].to_s | |
396 |
if back_url.present? && valid_back_url |
|
396 | if back_url.present? && valid_url = validate_back_url(back_url) | |
397 |
redirect_to( |
|
397 | redirect_to(valid_url) | |
398 | return |
|
398 | return | |
399 | elsif options[:referer] |
|
399 | elsif options[:referer] | |
400 | redirect_to_referer_or default |
|
400 | redirect_to_referer_or default | |
@@ -404,8 +404,9 class ApplicationController < ActionController::Base | |||||
404 | false |
|
404 | false | |
405 | end |
|
405 | end | |
406 |
|
406 | |||
407 |
# Returns t |
|
407 | # Returns a validated URL string if back_url is a valid url for redirection, | |
408 | def valid_back_url?(back_url) |
|
408 | # otherwise false | |
|
409 | def validate_back_url(back_url) | |||
409 | if CGI.unescape(back_url).include?('..') |
|
410 | if CGI.unescape(back_url).include?('..') | |
410 | return false |
|
411 | return false | |
411 | end |
|
412 | end | |
@@ -416,19 +417,36 class ApplicationController < ActionController::Base | |||||
416 | return false |
|
417 | return false | |
417 | end |
|
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 | return false |
|
433 | return false | |
421 | end |
|
434 | end | |
422 |
|
435 | |||
423 |
if |
|
436 | if path.match(%r{/(login|account/register)}) | |
424 | return false |
|
437 | return false | |
425 | end |
|
438 | end | |
426 |
|
439 | |||
427 |
if relative_url_root.present? && ! |
|
440 | if relative_url_root.present? && !path.starts_with?(relative_url_root) | |
428 | return false |
|
441 | return false | |
429 | end |
|
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 | end |
|
450 | end | |
433 | private :valid_back_url? |
|
451 | private :valid_back_url? | |
434 |
|
452 |
@@ -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