【问题标题】:Rails tag(:br) not considered as html_safeRails tag(:br) 不被视为 html_safe
【发布时间】:2014-08-02 15:56:30
【问题描述】:

最后回答。

我目前正在重构我的应用程序,我想知道如何缩短我的“if”,因为我在其中经常使用它们:

我想要的是换行符<br />,只有当值不为空时,所以,现在我这样写:

<% if @card.address.street.present? %>
 <%= @card.address.street.titleize %>
 <%= tag(:br) %> ## or plain html <br />
<% end %>

效果很好,但我敢肯定还有不那么罗嗦的方法。

我试过了:

<%= @card.address.street.titleize + tag(:br) if @card.address.street.present? %>

==> Washington Road '' ## br 标签不是 html_safed。

如果我这样做:

<%= raw @card.address.street.titleize + tag(:br) if @card.address.street.present? %>

等于:

<%== @card.address.street.titleize + tag(:br) if @card.address.street.present? %>

我工作得很好,但是我的代码暴露在 XSS 攻击之下。

所以,我试过了:

<%= @card.address.street.titleize + raw(tag(:br)) if @card.address.street.present? %>

<%= @card.address.street.titleize + tag(:br).html_safe if @card.address.street.present? %>

<%= @card.address.street.titleize + "<br />".html_safe if @card.address.street.present? %>

==> Washington Road '' ## br 标签仍然不是 html_safed。

Sanitize 对此有很好的效果,这样使用:

<%= sanitize(@card.address.street.titleize + tag(:br)) if @card.address.street.present? %>

但这是提高性能的最佳方式吗?

我最终使用了一个助手:

在 helpers/application_helper 内部

def line_break value
 sanitize(value) + tag(:br)
end

Helper 在控制器中加载

class UsersController < ApplicationController
helper ApplicationHelper

我在应用程序一中添加了这个助手。如果您希望在您的应用程序上使用不那么通用的东西,则首选模块。

与空参数一起使用的消毒将检查字符串中的 html,并将其删除。 如果你想要不那么重的东西,你可以使用 h() 来转义所有 html 而不是删除它。

在视图中

<%= line_break(@card.address.street.titleize) if @card.address.street.present? %>

我知道这纯粹是“写作速度问题”,但我们将不胜感激。

亲切的问候

【问题讨论】:

  • 无论如何这应该在一个助手中。
  • 当然戴夫,我会使用一个助手。我的问题主要是
    没有转义,即使我做了一个帮手,比如 line_break(@card.address.street.titleize) 和 def line_break(value) value + tag(:br) end

标签: ruby-on-rails string if-statement tags html-safe


【解决方案1】:

这并不是因为你的 br 标签是安全的还是不安全的。

街道字符串不安全,当您将安全字符串添加到不安全字符串时,结果仍然不安全。

你可以把它写成

<%= h(@card.address.street.titleize) + tag(:br) %>

h 进行转义并将结果标记为安全(因为它刚刚被转义)。

【讨论】:

  • 非常感谢您的解释
  • 因为我在 rails 4,而且 sanitize 方法看起来很漂亮,所以我最终使用了 空参数进行检查,然后通过删除它们而不是转义它们来删除所有注入 html 的尝试。它符合我的需要,但我还不清楚 unsafe+safe = unsafe 的逻辑,所以谢谢你的提示。
  • 谢谢。尝试了很多,但这是唯一有效的方法。
【解决方案2】:

试试看:

<% street = @card.address.street %>
<%= h(street.titleize) + tag(:br) if street.present? %>

OR(可读性较差但紧凑)

<%= (h(street.titleize) + tag(:br)) if ((street = @card.address.street) && street.present?) %>

祝你好运!

编辑: 由于 Frederick Cheung 的 comment 让我注意到与 html_safe 关联的 xss attack,我已经更新了答案并使用 h 进行逃生,Frederick。我可以删除这个答案,但它也显示代码减少,所以它可能对某人有帮助。

【讨论】:

  • 所有这些都允许 xss
  • 谢谢拉吉。不需要将@card.address.street 放在局部变量中, 可以正常工作:)
  • @user3181644 这是为了提高效率和避免代码重复。你可以看到你找到@card.address.street 两次......
  • 哦,好的。我同意它在代码重复方面看起来更好。乍一看,我并没有考虑使用局部变量来提高效率(因为查询已经在我的控制器中完成了),但现在这样使用听起来很有趣,我从来没有这样做过。
  • 精简版好像不行,我得在if语句外指定全局变量,比如
猜你喜欢
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-18
  • 2011-11-13
  • 1970-01-01
相关资源
最近更新 更多