首页 > 代码库 > RailsCase27 Cross Site Scripting 跨站点脚本攻击

RailsCase27 Cross Site Scripting 跨站点脚本攻击

跨站点脚本是开发过程中经常需要考虑的安全问题。此种情形发生在允许用户直接输入html、javascript脚本时。在下述的website中,我们并没有过滤输入的内容,导致一些安全漏洞。

Our site, showing the comments box.

如果在输入框中输入由<script>包围的内容,当页面被加载的时候,脚本将被执行,每次均将在前端展示。例如,如果输入<script>alert(’hello’)</script>并保存,每次浏览此页面时,都将看到alert的窗口。

嵌入页面的javascript脚本如下:
terminal
<h2>Comments</h2>
  <p>I‘ll start on this now - Paul</p>
  <p><script>alert(‘hello!‘);</script></p>
<hr/>

跨站点脚本可能被用于恶意的攻击。例如,可以读取站点上其他用户的cookie。将用户的cookie发送到远程服务器和alert内容一样的容易。cookie中的session id可被用来劫持其他用户的session。

The cookie information shown by JavaScript.

上述展示了cookie中的session key。

预防攻击

为了预防此种攻击,需要在页面呈现内容前,过滤用户的输入内容。之前,我们直接从数据库中获取comment的内容并输入到html stream中。Rails提供了输出前过滤内容的方法,h方法。

ruby
<% @task.comments.each do |comment| %>
  <p><%= h(comment.content) %></p>
<% end %>

此时,当加载页面时,可以看出脚本不再执行。h方法过滤了尖括号(“<”和“>”)(将尖括号用html这种的转义字符标识)以便内容可正常显示。

The comments are now safely escaped.

Rails也提供了  sanitize 方法,允许设置白名单,白名单中的标签将不被过滤。

防止攻击的另外一种方式

与内容在浏览器展现前,过滤内容不同,可以在将数据存储在数据库前将数据进行过滤。在控制器中,h方法是不可行的,可用CGI::escapeHTML()实现此功能。      

ruby
def create
    @task = Task.find(params[:task_id])
    @comment = @task.comments.new(params[:comment])
    @comment.content = CGI::escapeHTML(params[:comment][:content])
    @comment.save
    redirect_to task_path(@task)
  end
  1. http://en.wikipedia.org/wiki/Session_hijacking
原文地址:http://railscasts.com/episodes/27-cross-site-scripting?view=asciicast

RailsCase27 Cross Site Scripting 跨站点脚本攻击