缺点和支持采用一个自定义的`redirect_to`方法(Drawbacks and support

2019-10-30 01:56发布

为了每次用户重定向到自定义网页params包含redirect_uri值我正在评估使用自定义的redirect_to方法,这种方式(由@kiddorails ):

class ApplicationController < ActionController::Base
  def custom_redirect_to(url)
    redirect_to (params[:redirect_uri].present? ? params[:redirect_uri] : url)
  end
end

def create
  @post = Post.new(params)
  if @post.save
    custom_redirect_to @post
  else
    render 'new'
  end
end

不过,我想知道可能的弊端,并接收采用上述解决方案支持。

Answer 1:

允许重定向目标,通过没有任何验证的URL参数设置是为您的用户有潜在危险的,因为它使钓鱼尝试更容易。

攻击者可以发送链接到你的用户,如

http://my-trusted-site.com/some/action/path?redirect_uri=malicious-site-that-looks-like-trusted-site.com

,许多用户将只能看到域部分并没有意识到,他们点击该链接后结束。

开放Web应用安全项目(OWASP)为此认为这是一个漏洞 :

当Web应用程序接受不受信任的输入,可能导致Web应用程序请求重定向到包含不可信的输入中的URL未经验证的重定向和转发是可能的。 通过修改网址不可信输入到一个恶意网站,攻击者可能会成功地发动网络钓鱼诈骗,窃取用户凭据。 因为在修改的链路服务器名称是相同的原始网站,网络钓鱼企图可能具有更值得信赖的外观。 未经验证的重定向和转发攻击,也可以用于恶意手艺,将通过应用程序的访问控制检查,然后转发攻击者特权功能,他们通常无法访问的URL。

你执行重定向之前仔细检查REDIRECT_URI参数是很重要的。

但是,因为适当的验证是棘手的,容易出错,甚至更好的想法是不接受摆在首位URI参数,而是让某些关键字而不是指定的用户会被重定向。

class ApplicationController < ActionController::Base

    protected

  def dynamic_redirect_to(default_route, options)
    options.stringify_keys!

    redirect_to options.fetch(params[:redirect_to], default_route)
  end
end

现在,您可以定义任意数量的事先允许的关键字,可以用作的?redirect_to=参数:

def create
  @post = Post.new(params)
  if @post.save
    dynamic_redirect_to post_path(@post), edit: edit_post_path(@post)
  else
    render 'new'
  end
end

如果?redirect_to=edit设置,用户被重定向到编辑页面。 如果没有设置该参数或包含未指定的关键字,就会被重定向到默认post_path(@post)来代替。



Answer 2:

我同意janfoeh上面说的。 但要实现你的要求,我砍死左右重定向的Rails代码 ,使其更简单。

使文件的配置/初始化/ redirecting.rb有:

require 'abstract_controller/base'
module ActionController
  module Redirecting
    extend ActiveSupport::Concern

    include AbstractController::Logger
    include ActionController::RackDelegation
    include ActionController::UrlFor

    def _compute_redirect_to_location(options)
      if redirect_url = session.delete(:redirect_uri)
        options = redirect_url
      end
      case options
        # The scheme name consist of a letter followed by any combination of
        # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
        # characters; and is terminated by a colon (":").
        # See http://tools.ietf.org/html/rfc3986#section-3.1
        # The protocol relative scheme starts with a double slash "//".
      when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i
        options
      when String
        request.protocol + request.host_with_port + options
      when :back
        request.headers["Referer"] or raise RedirectBackError
      when Proc
        _compute_redirect_to_location request, options.call
      else
        url_for(options)
      end.delete("\0\r\n")
    end
  end
end

在您的应用程序/控制器/ application_controller.rb:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.

  before_action :set_redirect_uri
  protect_from_forgery with: :exception

  def set_redirect_uri
    session[:redirect_uri] = params[:redirect_uri] if params[:redirect_uri].present?
  end
end

瞧! 现在,您可以继续使用原来的redirect_to ,每当redirect_uri中的URL提供的,它会设置URL中的会话和自动覆盖。 :)

:我清除session[:redirect_uri]只有当redirect_to被调用。 您可以轻松地修改该行为以重设此届取决于需求。



文章来源: Drawbacks and support for adopting a custom `redirect_to` method