ruby中的双等号==问题详解

 更新时间:2016年02月15日 08:53:34   投稿:hebedich  
Ruby里面有4种比较方法,equal?, eql?, ==, ===,而且在不同的类里面表现的很不一样。在使用的时候也特别容易搞糊涂。 本文先给大家讲述一下==号的用法及使用中应该注意的地方

前两天在写代码的时候,突然收到警告说项目代码中存在 XSS 漏洞,遂立即根据报告的 URL 排查页面代码,虽然很快就修复了,而且同样问题的讨论两年前就有了,一般来说相对有经验的同学也应该都知道这个点,但是还是觉得有必要写出来,再次提醒一下其他小伙伴,避免踩坑。

问题根源

其中,在找到的漏洞出现的地方,都存在类似以下这样的 slim 代码:

input class='xxx' value==params[:account]

问题就出在双等号 == 上,因为在 slim 跟 ERB 模板(其他模板比如 HAML 之类的就不清楚了)中,双等号其实是 Rails 的 raw 这个 helper 方法的缩写

To insert something verbatim use the raw helper rather than calling html_safe:
<%= raw @cms.current_template %> <%# inserts @cms.current_template as is %>
or, equivalently, use <%==:
<%== @cms.current_template %> <%# inserts @cms.current_template as is %>

也就是说上面的代码等同于:

input class='xxx' value=raw(params[:account])

其中 raw 方法在 Rails 文档中的解释是这样子的:

This method outputs without escaping a string. Since escaping tags is now default, this can be used when you don't want Rails to automatically escape tags. This is not recommended if the data is coming from the user's input.

大概意思就是,这个方法将会跳过对传入的字符串进行标签过滤以及其他处理,直接将字符串输出到 HTML 中。
所以到现在原因就很清晰了,因为不小心在代码里多加了一个等号,变成了双等号,导致将会直接把用户的输入输出到待渲染的 HTML 中,在不自知的情况下留下了 XSS 漏洞。于是乎,修复方案仅需去掉一个等号即可:

input class='xxx' value=params[:account]

这样,Rails 就能继续自动过滤输入的 :account 的参数并且自动过滤恶意内容了。

raw、String#html_safe 以及 <%== %>
在查看 raw 方法的文档时,顺便看了其源码,极其简单,只有一行:

# File actionview/lib/action_view/helpers/output_safety_helper.rb, line 16
def raw(stringish)
 stringish.to_s.html_safe
end

raw 只是先确保将 stringish 参数转化为字符串,然后调用了 String#html_safe 方法而已。而且在 String#html_safe 的文档中,同样反复强调慎重使用这两个方法:

It will be inserted into HTML with no additional escaping performed. It is your responsibilty to ensure that the string contains no malicious content. This method is equivalent to the raw helper in views.

所以,可以总结一下,以下三种写法的代码都是等价的,都是不安全的:

input class='xxx' value==params[:account]
input class='xxx' value=raw(params[:account])
input class='xxx' value=params[:account].html_safe

那在切实需要输出包含 HTML 内容比如富文本编辑器编辑的内容时,如何保证安全?
方案很简单,只需要使用文档中推荐的 sanitize helper 方法:

It is recommended that you use sanitize instead of this method(html_safe).
(#sanitize)Sanitizes HTML input, stripping all tags and attributes that aren't whitelisted.

或者使用一些其他第三方的 gem 用来做过滤处理。

总结

  1. 不要使用双等号缩写的方式,以避免其他人(比如项目里的 Rails 新手)在不了解的情况下照着滥用;
  2. 尽可能不用 raw helper 或者 String#html_safe 方法,尽可能使用 #sanitize;
  3. 多借助工具进行自动扫描,比如 brakeman,能够快速高效检测出包括 XSS 漏洞在内的多种安全隐患。

相关文章

  • ruby实现的插入排序和冒泡排序算法

    ruby实现的插入排序和冒泡排序算法

    最近刚开始学ruby为了练习一下基本语法的使用,用ruby写了一下插入排序算法,可能有些从C#翻译过来的痕迹
    2014-05-05
  • CentOS 7下配置Ruby语言开发环境的方法教程

    CentOS 7下配置Ruby语言开发环境的方法教程

    对于新入门的开发者,如何安装 Ruby, Ruby Gems 和 Rails 的运行环境可能会是个问题,下面这篇文章主要给大家分享了在CentOS 7下配置Ruby语言开发环境的方法教程,文中介绍的非常详细,需要的朋友们下面来一起看看吧。
    2017-05-05
  • 冒泡排序算法及Ruby版的简单实现

    冒泡排序算法及Ruby版的简单实现

    冒泡排序为最基本的排序算法之一,其时间复杂度为O(n^2),这里我们就来简单看一下冒泡排序算法及Ruby版的简单实现,首先还是先来了解算法原理:
    2016-05-05
  • ruby中执行周期性任务(定时任务)的3种方法

    ruby中执行周期性任务(定时任务)的3种方法

    这篇文章主要介绍了ruby中执行周期性任务(定时任务)的3种方法,本文通过使用whenever、sidetiq、clockwork等gem实现,需要的朋友可以参考下
    2014-10-10
  • Ruby中百分号和字面值的使用示例

    Ruby中百分号和字面值的使用示例

    这篇文章主要介绍了Ruby中百分号和字面值的使用示例,作者给出了相关编程风格上的一些建议,需要的朋友可以参考下
    2015-08-08
  • ruby环境中自动编译sass教程

    ruby环境中自动编译sass教程

    这篇文章主要介绍了ruby环境中自动编译sass教程,本文讲解了ruby环境的安装、sass环境的安装以及sass的常用编译命令使用示例,需要的朋友可以参考下
    2015-02-02
  • Ruby rails 页面跳转(render和redirect_to)

    Ruby rails 页面跳转(render和redirect_to)

    今天在做R.R.log的时候发现个问题,在修改密码的时候如果没有通过校验,没有显示校验错误的信息。
    2009-05-05
  • 编写Ruby脚本来对Twitter用户的数据进行深度挖掘

    编写Ruby脚本来对Twitter用户的数据进行深度挖掘

    这篇文章主要介绍了编写Ruby脚本来对Twitter用户的数据进行深度挖掘的一些例子,通过调用Twitter API来实现各种功能(内地注意墙),需要的朋友可以参考下
    2015-11-11
  • Java版的Ruby解释器 JRuby简介

    Java版的Ruby解释器 JRuby简介

    JRuby是面向Ruby、基于Java虚拟机(JVM)的一种解释程序,它结合了Ruby语言的简易性和功能强大的JVM的执行机制,包括与Java库 全面集成。
    2014-06-06
  • Ruby编程中关于中断和返回的用法教程

    Ruby编程中关于中断和返回的用法教程

    这篇文章主要介绍了Ruby编程中关于中断和返回的用法教程,作者用代码举例讲解了其中需要注意的问题,需要的朋友可以参考下
    2015-05-05

最新评论