5.1.2 Safe Strings
Active Support has the concept of (html) safe strings. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
Strings are considered to be unsafe by default:
""
.html_safe?
# => false
|
You can obtain a safe string from a given one with the html_safe
method:
s =
""
.html_safe
s.html_safe?
# => true
|
It is important to understand that html_safe
performs no escaping whatsoever, it is just an assertion:
s =
"<script>...</script>"
.html_safe
s.html_safe?
# => true
s
# => "<script>...</script>"
|
It is your responsibility to ensure calling html_safe
on a particular string is fine.
If you append onto a safe string, either in-place with concat
/<<
, or with+
, the result is a safe string. Unsafe arguments are escaped:
""
.html_safe +
"<"
# => "<"
|
Safe arguments are directly appended:
""
.html_safe +
"<"
.html_safe
# => "<"
|
These methods should not be used in ordinary views. Unsafe values are automatically escaped:
<%=
@review
.title
%>
<%
# fine, escaped if needed
%>
|
To insert something verbatim use the raw
helper rather than callinghtml_safe
:
<%=
raw
@cms
.current_template
%>
<%
# inserts @cms.current_template as is
%>
|
or, equivalently, use <%==
:
<%=
=
@cms
.current_template
%>
<%
# inserts @cms.current_template as is
%>
|
The raw
helper calls html_safe
for you:
def
raw(stringish)
stringish.to_s.html_safe
end
raw方法本来就是包含了html_safe方法!!
起因都是 raw
,它和 html_safe
是同义的。我发现很多人都误解了这两个 helper 的用法,再强调一次它的意思是:
我要裸奔!
Rails 框架本身做了很多安全措施,在默认情况下,template 里的所有字符串都会被过滤:
<%= danger_string %> <!-- 安全 -->
这段代码是安全的,但是这段代码:
<%= raw danger_string %> <!-- 危险 -->
就告诉模板系统关掉了安全过滤,这是非常危险的。通常谈到 raw 的时候都因为要输出 html 内容,这时候应该用 sanitize
,这是一个基于白名单的过滤方法:
<%= sanitize danger_string %> <!-- 只要不开危险的标签属性名单就安全 -->
sanitize 可以在方法级别和全局级别设置白名单标签和属性,详细可以看文档 http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html
总结:如果你不知道自己知不知道自己在干什么,别用 raw 和 html_safe,用 sanitize。
补充1:helper 里面也要避免 raw,避免在 helper 拼接 HTML
补充2:sanitize 要放在字符串处理链的末尾