我有一个显示我文章内容的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
记录,对吗?用户还能如何操纵它?
谢谢!
编辑:当找不到文章并引发错误时,我绝对应该防止这种情况,但我认为这更像是一个糟糕的设计而不是安全漏洞
Brakeman 发出警告,因为代码正在从数据库中获取信息并将其输出到视图中而不对其进行转义。默认情况下,Brakeman 将数据库中的值视为潜在危险。在这种情况下,您可能知道文章内容旨在为 HTML,并且可以安全地输出而不会对其进行转义。如果不希望使用数据库中的值警告 XSS,可以使用 --ignore-model-output
选项。
(您在答案中链接的问题并不真正相关。预计Brakeman将警告使用具有潜在危险值的raw
/html_safe
。
Ok 经过一番挖掘找到了答案。
它显然与html_safe
和raw
有关(这只是html_safe
的别名)。该问题特定于 Brakeman,并在此处概述
该线程说该问题已得到承认并解决,但使用最新版本仍然对我不起作用。
我解决了如下
控制器:
def show
@article = Article.find(params[:id])
@article_content = view_context.raw(@article.content)
end
视图:
...
<li class="content"><%= @article_content %></li>
...
本质上,我们事先将文章内容标记为html_safe
(使用别名 raw()
),因此它不会在视图中引起问题。
比我想要的更混乱,但它有效
如果你在模型上存储html,并且你使用的是Rails 4.2++,你可以考虑使用sanitize
助手(docs)。
,您可以允许特定标签(例如链接):
<%= sanitize @article.content, tags: %w(a), attributes: %w(href) %>
文档有很多很好的例子。
如果您想了解更多信息,这是另一篇文章。