Rails Brakeman警告:动态渲染路径误报?

时间:2012-06-29 14:48:33

标签: ruby-on-rails ruby ruby-on-rails-3 brakeman

我刚开始使用Rails,所以我正在使用Brakeman来了解我的新手代码中的潜在漏洞。它在我的show.js.erb文件中抛出了一个关于以下代码的高可信度“动态渲染路径”警告:

$('#media-fragment').html('<%= escape_javascript(render(params[:partial])) %>');

我实际上预计这是一个问题,所以毫不奇怪。所以我把它改成了以下内容:

  # controller:
  def show
    if legal_partial?
      @allowed_partial = params[:partial]
    else
      raise StandardError, "unexpected partial request: #{params[:partial]}"
    end
  end

  private

  def legal_partial?
    %w(screenshots video updates).include? params[:partial]
  end

  # ...
  # show.js.erb
  $('#media-fragment').html('<%= escape_javascript(render(@allowed_partial)) %>');

虽然我相信代码现在是安全的,但Brakeman仍对此不满意。是否有更惯用的方法来控制基于用户输入的部分渲染?

2 个答案:

答案 0 :(得分:7)

更新(2016年2月5日):

截至Brakeman 3.0.3已修复此问题。

如果legal_partial?方法内联如下:

def show
  if %w(screenshots video updates).include? params[:partial]
    @allowed_partial = params[:partial]
  else
    raise StandardError, "unexpected partial request: #{params[:partial]}"
  end
end

Brakeman将能够检测到后卫状态,并且不再警告稍后的render来电。


原始回答:

不幸的是,Brakeman并不知道if legal_partial?是一个合适的后卫。它只知道params[:partial]已分配给@allowed_partial,然后传递给render

您可以告诉我@allowed_partial永远是安全的价值。那时,你必须考虑是否有必要增加复杂性以使工具满意。

举个例子,你可以这样做:

def show
  render_allowed_partial params[:partial]
end

def render_allowed_partial name
  if %w(screenshots video updates).include? name
    @allowed_partial = name
  else
    raise StandardError, "unexpected partial request: #{params[:partial]}"
  end
end

这基本上是相同的,除非你现在隐藏了来自Brakeman的@allowed_partial作业。

(警告:这不一定是“最好”的方式。)

答案 1 :(得分:0)

使用 brakeman 4.2.0

尝试渲染特定的手动定位和命名的模板时,我遇到了类似的问题。我的应用的每个产品都需要特定的命名模板。模板名称来自控制器参数params[:a_particular_slug].underscore

我用这样的东西解决了:

  def show
    if @products = Product.where(a_slug: params[:a_particular_slug])
      render template: lookup_context.find(params[:a_particular_slug].underscore, ["featured_products"])
    else
      render_404
    end
  end

我在这里寻找模板。如果你需要使用partial,请注意lookup_context.find设置为true的第三个参数允许搜索部分。

您可以找到有关lookup_context.find here

的更多信息

希望这有帮助。