为什么我的视图被标记为 XSS 漏洞?

Why is my view being flagged as an XSS vulnerability?

我有一个 show 路由显示我文章的内容

控制器:

def show
  @article = Article.find(params[:id])
end

查看:

...
<li class="content"><%= @article.content.html_safe %></li>
...

当 运行 Brakeman 时,它将上述标记为潜在的跨站点脚本 (XSS) 漏洞

Unescaped model attribute near line 34: Article.find(params[:article_id]).content

我想弄清楚 XSS 到底是什么,是什么让它容易受到攻击?如果有人在路由中的 params[:id] 字段中注入一些恶意文本或输入(例如 /articles/BAD_INPUT),那么 Article.find() 将找不到该文章并引发错误

视图呈现的唯一方式是找到有效的 Article 记录,对吧?用户还能如何操作它?

谢谢!

编辑: 我绝对应该防止找不到文章并引发错误的情况,但我认为这更像是一个糟糕的设计而不是安全漏洞

好的,经过一番挖掘后找到了答案。

它显然与 html_saferaw(这只是 html_safe 的别名)有关。该问题特定于 Brakeman 并概述 here

该帖子说问题已得到确认并已解决,但使用最新版本对我来说仍然无效。

我是这样解决的

控制器:

def show
  @article = Article.find(params[:id])
  @article_content = view_context.raw(@article.content)
end

查看:

...
<li class="content"><%= @article_content %></li>
...

本质上,我们事先将文章内容标记为 html_safe(使用别名 raw()),因此它不会在视图中引起问题。

比我想要的更混乱,但它有效

Brakeman 发出警告是因为代码正在从数据库中获取信息并将其输出到视图中而不进行转义。默认情况下,Brakeman 将数据库中的值视为潜在危险。在这种情况下,您可能知道文章内容是 HTML 并且无需转义即可安全输出。如果你不想警告来自数据库的值的 XSS,你可以使用 --ignore-model-output 选项。

(您在答案中链接的问题并没有真正相关。Brakeman 应该警告使用 raw/html_safe 具有潜在危险值。)

如果您在模型上存储 html 并且您使用的是 Rails 4.2++,您可以考虑使用 sanitize 助手 (docs)。

例如,您可以允许特定标签(例如链接):

<%= sanitize @article.content, tags: %w(a), attributes: %w(href) %>

docs有很多很好的例子。

如果您想了解更多信息,请点击此处another write-up