diff app/controllers/application_controller.rb @ 1516:b450a9d58aed redmine-2.4

Update to Redmine SVN revision 13356 on 2.4-stable branch
author Chris Cannam
date Tue, 09 Sep 2014 09:28:31 +0100
parents e248c7af89ec
children dffacf8a6908 2e8063097240
line wrap: on
line diff
--- a/app/controllers/application_controller.rb	Mon Mar 17 08:54:02 2014 +0000
+++ b/app/controllers/application_controller.rb	Tue Sep 09 09:28:31 2014 +0100
@@ -44,6 +44,7 @@
     unless api_request?
       super
       cookies.delete(autologin_cookie_name)
+      self.logged_user = nil
       render_error :status => 422, :message => "Invalid form authenticity token."
     end
   end
@@ -375,23 +376,42 @@
 
   def redirect_back_or_default(default)
     back_url = params[:back_url].to_s
-    if back_url.present?
-      begin
-        uri = URI.parse(back_url)
-        # do not redirect user to another host or to the login or register page
-        if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
-          redirect_to(back_url)
-          return
-        end
-      rescue URI::InvalidURIError
-        logger.warn("Could not redirect to invalid URL #{back_url}")
-        # redirect to default
-      end
+    if back_url.present? && valid_back_url?(back_url)
+      redirect_to(back_url)
+      return
     end
     redirect_to default
     false
   end
 
+  # Returns true if back_url is a valid url for redirection, otherwise false
+  def valid_back_url?(back_url)
+    if CGI.unescape(back_url).include?('..')
+      return false
+    end
+
+    begin
+      uri = URI.parse(back_url)
+    rescue URI::InvalidURIError
+      return false
+    end
+
+    if uri.host.present? && uri.host != request.host
+      return false
+    end
+
+    if uri.path.match(%r{/(login|account/register)})
+      return false
+    end
+
+    if relative_url_root.present? && !uri.path.starts_with?(relative_url_root)
+      return false
+    end
+
+    return true
+  end
+  private :valid_back_url?
+
   # Redirects to the request referer if present, redirects to args or call block otherwise.
   def redirect_to_referer_or(*args, &block)
     redirect_to :back
@@ -554,7 +574,7 @@
 
   # Returns a string that can be used as filename value in Content-Disposition header
   def filename_for_content_disposition(name)
-    request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
+    request.env['HTTP_USER_AGENT'] =~ %r{(MSIE|Trident)} ? ERB::Util.url_encode(name) : name
   end
 
   def api_request?