常量
| HTML_ESCAPE | = | { "&" => "&", ">" => ">", "<" => "<", '"' => """, "'" => "'" } |
| HTML_ESCAPE_ONCE_REGEXP | = | /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/ |
| INVALID_TAG_NAME_FOLLOWING_REGEXP | = | /[^#{TAG_NAME_FOLLOWING_CODEPOINTS}]/ |
| INVALID_TAG_NAME_START_REGEXP | = | /[^#{TAG_NAME_START_CODEPOINTS}]/ |
| SAFE_XML_TAG_NAME_REGEXP | = | /\A[#{TAG_NAME_START_CODEPOINTS}][#{TAG_NAME_FOLLOWING_CODEPOINTS}]*\z/ |
| TAG_NAME_FOLLOWING_CODEPOINTS | = | "#{TAG_NAME_START_CODEPOINTS}\\-.0-9\u{B7}\u{0300}-\u{036F}\u{203F}-\u{2040}" |
| TAG_NAME_REPLACEMENT_CHAR | = | "_" |
| TAG_NAME_START_CODEPOINTS | = | "@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \ "\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \ "\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}" |
遵循 XML 要求: www.w3.org/TR/REC-xml/#NT-Name |
||
类公共方法
html_escape_once(s) 链接
一个用于转义 HTML 的辅助方法,不会影响已转义的实体。
html_escape_once('1 < 2 & 3') # => "1 < 2 & 3" html_escape_once('<< Accept & Checkout') # => "<< Accept & Checkout"
来源: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/erb/util.rb, line 63 def html_escape_once(s) s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE).html_safe end
json_escape(s) 链接
一个用于转义 JSON 字符串中 HTML 实体的辅助方法。具体来说,&, > 和 < 字符被替换为它们对应的 Unicode 转义形式——u0026, u003e, 和 u003c。Unicode 序列 u2028 和 u2029 也被转义,因为它们在某些 JavaScript 引擎中被视为换行符。在 JSON 字符串的上下文中,这些序列与原始字符具有相同的含义,因此假设输入是有效且格式正确的 JSON 值,则输出在解析后具有相同的含义。
json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"}) # => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}" json_escape(json) # => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}" JSON.parse(json) == JSON.parse(json_escape(json)) # => true
此方法的预期用途是在将 JSON 字符串包含在 script 标签中之前对其进行转义,以避免 XSS 漏洞。
<script> var currentUser = <%= raw json_escape(current_user.to_json) %>; </script>
有必要对 json_escape 的结果使用 raw,这样引号就不会被转换为 " 实体。 json_escape 不会自动将结果标记为 HTML 安全,因为原始值不能安全地用于 HTML 属性中。
如果你的 JSON 将在下游用于插入 DOM,请注意它是否通过 html() 插入。大多数 jQuery 插件都会这样做。如果是这样,请确保对你的 JSON 返回的任何用户生成的内容进行 html_escape 或 sanitize。
如果你需要在 HTML 的其他地方输出 JSON,你可以这样做,因为任何不安全的字符(包括引号)都会被自动转义。
<div data-user-info="<%= current_user.to_json %>">...</div>
警告:此辅助方法仅适用于有效的 JSON。将其用于非 JSON 值将导致严重的安全漏洞。例如,如果将示例中的 current_user.to_json 替换为用户输入,浏览器将愉快地将该字符串作为 JavaScript 进行 eval()。
此方法执行的转义与 Active Support JSON 编码器在 ActiveSupport.escape_html_entities_in_json 设置为 true 时执行的转义相同。因为此转换是幂等的,所以即使 ActiveSupport.escape_html_entities_in_json 已经是 true,也可以应用此辅助方法。
因此,当你不确定 ActiveSupport.escape_html_entities_in_json 是否已启用,或者你不确定你的 JSON 字符串来自何处时,建议你始终应用此辅助方法(其他库,如 JSON gem,默认不提供这种保护;此外,一些 gem 可能会覆盖 to_json 以绕过 Active Support 的编码器)。
来源: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/erb/util.rb, line 124 def json_escape(s) result = s.to_s.dup result.gsub!(">", '\u003e') result.gsub!("<", '\u003c') result.gsub!("&", '\u0026') result.gsub!("\u2028", '\u2028') result.gsub!("\u2029", '\u2029') s.html_safe? ? result.html_safe : result end
xml_name_escape(name) 链接
一个用于转义 XML 标签名称和属性名称的辅助方法。
xml_name_escape('1 < 2 & 3') # => "1___2___3"
它遵循规范的要求: www.w3.org/TR/REC-xml/#NT-Name
来源: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/erb/util.rb, line 142 def xml_name_escape(name) name = name.to_s return "" if name.blank? return name if name.match?(SAFE_XML_TAG_NAME_REGEXP) starting_char = name[0] starting_char.gsub!(INVALID_TAG_NAME_START_REGEXP, TAG_NAME_REPLACEMENT_CHAR) return starting_char if name.size == 1 following_chars = name[1..-1] following_chars.gsub!(INVALID_TAG_NAME_FOLLOWING_REGEXP, TAG_NAME_REPLACEMENT_CHAR) starting_char << following_chars end