手记

Rails与web安全[Web安全大家谈]


        据说现在一台pc(Windows系统)上网的时候,如果没有任何杀毒软件防火墙,那么十分钟之内就会被沦陷为病毒之城。为什么会如此呢?因为你上网的时候,可能有的网站会被植入病毒,植入木马什么的,网站的用户只要一登陆,如果没有任何防护措施,那么你的机器肯定会马上被攻陷了。当然了,网站也不是故意要挂病毒和木马给用户的,主要是有些站点在开发之初或上线之后都没有考虑过web安全的问题,以致于存在很多安全隐患,导致被恶意的Hacker所控制,从而发生上述一幕。那么该如何防范呢?

     广告之后更精彩:

            趋势科技, 让Hacker病毒们,去死!

     第一,对于普通用户来说,可以下载一些著名的安全软件来使用,比如趋势科技的WTP, 网站管理员也可以使用趋势的防毒墙。但是我觉得,要解决根本,还是从站点开发之初来防范这些漏洞。 当然,漏洞也是变化的,上线以后还是部署个趋势的防毒墙更保险。

=。=

身为一名Rails开发者,就说一下web安全十大漏洞和rails开发中该如何防范这些漏洞。

A1 - Cross Site Scripting (XSS)

这是攻击者利用在网站里嵌入javascript来进行获取受害人的cookie信息。

     Rails2.0对XSS攻击的防范也得到增强,TextHelper#sanitize由黑名单改为了白名单实现。具体攻击方法在这里:[url]http://www.rorsecurity.info/2007/05/01/cross-[/url] site-scripting-user-agent-injection-attack-methods/

   有助于我们检测自己的项目。

   rails策略:

       1.在view里加入h方法,safeERB插件的作用ms不是为了帮助我们免除这一步。

       2.用whitelist,刚才所说的rails2。0开启了这个方法TextHelper#sanitize.

       3.在使用BlueCloth和RedCloth的时候,应该联合WhiteList来用,避免引发安全问题。

      4。在Rails1.2.3版本之前,不要使用to_json方法,小心殆害!

A2 - Injection Flaws

注入攻击有很多种,SQL,LDAP,XPath,XSTL,HTML,XML,OS COMMAND等等,但主要是SQL注入比较突出,我们这里只关注SQL注入的解决方法。

Don't use Project.find(:all, :conditions => "name = '#{params[:name]}'")

           Do use Project.find(:all, :conditions => ["name = ?", params[:name]])

           sql注入是指攻击者从客户端手动输入参数,使参数传到数据库服务器,混入到sql查询语句里把一些信息返回到客户端,即浏览器显示。

         Project.find(:all, :conditions => "name = '" + params[:name] + "'")

        Project.find(:all, :conditions => "name = '#{params[:name]}'")

         比如这两个例子,将会受到sql注入的攻击:

         攻击者只要输入:' or 1 -, 这个时候rails生成的sql语句就变成了:

     select * from projects  where name = '' or 1 --'

     因为在mysql里的boolean值是1,这个 – 符号(# 和 /*也是注释)是sql的注释,后面所有的一切都会被忽略,所以我们这个sql句相当于

      select * from projects

 利用sql 注入如何绕过权限验证:

   User.find(:first, "login = '#{params[:name]}' AND password =  '#{params[:password]}'")

     params[:name] = ' OR '1'='1

     params[:password] = ' OR '2'>'1

     params[:name] = ' OR login LIKE '%a%

     params[:password] = ' OR ISNULL(1/0) #

   Unauthorized Reading

   参见:[url]http://www.rorsecurity.info/2007/05/19/sql-injection/[/url]

   rails的解决办法就是:

   1。用占位符号

      User.find(:first, :conditions => ["login = ? AND password = ?", params[:name],

params[:password]])

  2。用hash(rails版本是在1.2以上)

     User.find(:first, :conditions => {:login => params[:name],

:password => params[:password]})

   3。在保证上述两点的基础上,把查询方法放在model里。这样会更加安全。

   4. 所有rails根据model属性自己生成的find_by_xxx方法是很安全的,比如:

      find_by_name, 等。

  5. find_by_sql 也是很安全的。

A3 - Malicious File Execution

这个安全隐患在Rails1.1.6就已经解决了,1.1.6以下的项目需要打个补丁,但是rails2.0出来了,还是升级吧

相关:

Working with files

这是关于文件上传的安全策略:

[url]http://www.rorsecurity.info/2007/03/27/working-with-files-in-rails/[/url]

参见:Agile 开发之道2nd,610页。

A4 - Insecure Direct Object Reference

在rails里,只要注意不要把内部的controller方法暴露出来,即,不要把private方法误写到publice方法里就行,对一些action和controller做一个全局的异常处理,就不会被攻击者把你应用程序攻击的肠子都流出来了。

A5 - Cross Site Request Forgery (CSRF)

传说中的跨站伪装请求攻击(通常也叫one click attack"或者session riding,通常缩写为CSRF或者XSRF)

听起来有点像css/xss跨站脚本攻击有点类似,但实质不同,CSRF比起css/xss来更加危险,因为这种攻击难以防范(主要是因为不大流行,所以防范资源比较缺乏)。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。网网这两种攻击方法是买一送一的关系。利用XSS伪装受信任用户,利用这个受信任用户来进行CSRF攻击来利用网站。

例子:一个网站用户Bob可能正在浏览聊天论坛,而同时另一 个用户Alice也在此论坛中,并且后刚刚发布了一个具有Bob银行链接的图片消息。设想一下,Alice编写了一个在Bob的银行站点上进行取款的form提交的链接,并将此链接作为图片tag。如果Bob的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当Bob的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经Bob同意的情况下便授权了这次事务。

   CSRF是一种依赖web浏览器的、被混淆过的代理人攻击(deputy attack)。在上面银行示例中的代理人是Bob的web浏览器,它被混淆后误将Bob的授权直接交给了Alice使用。

下面是CSRF的常见特性:

依靠用户标识危害网站

利用网站对用户标识的信任

欺骗用户的浏览器发送HTTP请求给目标站点

  CSRF攻击依赖下面的假定:

攻击者了解受害者所在的站点

攻击者的目标站点具有持久化授权cookie或者受害者具有当前会话cookie

目标站点没有对用户在网站行为的第二授权

       防范措施

在form中包含秘密信息、用户指定的代号作为cookie之外的验证。那些导致对安全产生"副作用"的请求应该总使用Post方式发送。Post方式不会在web服务器和代理服务器日志中留下数据尾巴,然而Get方式却会留下数据尾巴

   Rails的策略:

      1。慎用get请求,也就是上面所说的, 那些导致对安全产生"副作用"的请求应该总使用Post方式发送。

      2。Use the Csrf_killer plugin to include a security token in forms.(插件方式过期,但是使用rails2.0y一下版本的项目需要注意)

      在Rails2.0中,通过在form中增加特殊字段来防止CRSF攻击,这一功能在新应用中默认是开启的。

A6 - Information Leakage and Improper Error Handling

一些重要的信息泄露一般是通过程序里的异常信息透露给攻击者的,如果异常信息太详细,那么就很危险了,所以和上面一条一样,要进行异常处理。全局的异常处理。

def rescue_action_in_public(exception)

case exception.class.name

when 'ActiveRecord::RecordNotFound','::ActionController::UnknownAction','::ActionController::RoutingError'

RAILS_DEFAULT_LOGGER.error("404 displayed")

render(:file => "#{RAILS_ROOT}/public/404.html", :status => "404 Error")

else

RAILS_DEFAULT_LOGGER.error("500 displayed")

render(:file => "#{RAILS_ROOT}/public/500.html", :status => "500 Error")

end

end

A7 - Broken Authentication and Session Management

1.session hijacking(session劫持).

      session劫持,是被非法用户拿到整个session信息(cookie).然后让你的所有信息暴露。

     

      how: 是通过网络监听来获取。有些sniffer软件,等等。。。

      Countermeasures:

       对策1: Encrypt the traffic using SSL

             虽然ssl比较慢,但是还是很安全的,需要在environment.rb中加入:

             ActionController::Base.session_options[:session_secure] = true

      对策2 : Include additional information (user agent, IP address, …) in the cookie

              我们在session里加上一些额外的信息,在每一次请求都去验证它。

      对策3 : Create a new session when someone successfully logs in.

              用reset_session,但是你不得不把老的session里的数据copy过来。比如user_id.

      对策4 : 在用户注销以后让session无效。设置session过期时间。

    2.Session fixation(Session定制攻击)

         how:攻击者通过得到用户合法的session id,并强迫浏览器使用这个session_id 来进行攻击。在php里,session管理器接受任何的session id,即便这个id不存在,但是ruby on rails里是不可能的,ruby on rails只接受已经生成的session id,所以攻击者会访问这个rails站点来获取合法的session id,然后传递给第三方用户,如果使用这个session id可以登录成功,那么其他的session id也一样不安全。

在得到session id之后,就会用html 标签<META>来对浏览器注入session id强迫浏览器使用这个session id来登录站点。

<meta http-equiv=Set-Cookie content="_session_id=4cf69dc5fee46251bdc1f99ef55f52b6">

这是危险的!

    对策:

           目前最好的对策是: 用reset_session,也就是上面所说的.

   3.设置cookie过期时间( Expiration of cookies )

        1).Client side  客户端可以指定一个固定的时间。e.g :

            ActionController::Base.session_options[:session_expires] = Time.local(2007,"jan")

            但是记住用户可以改变这个过期时间

        2). Server side

            Remove old sessions  from your hard disk or database  Rails默认不会清除session,我们来自己指定。

           class SessionCleaner

        def self.remove_stale_sessions

          CGI::Session::ActiveRecordStore::Session.

          destroy_all( ['updated_on <?', 20.minutes.ago] )

        end

     end

     And then invoke the remove_stale_sessions method every 10 minutes via;

     */10 * * * * ruby /full/path/to/script/runner

     -e production "SessionCleaner.remove_stale_sessions"

        这是防止攻击者是通过写一个脚本来使用被劫持的session持续攻击。但是我们需要另一个session 存储器,像插件SQLSessionStore ,或者an update of the ActiveRecordStore migration so it has a created_at field.

      3) 动态设置session过期时间。这里有个插件:

       [url]http://blog.codahale.com/2006/04/08/dynamic-session-expiration-times-with-rails/[/url]

      rails2。0里可能不适用了,我们可以参照这个插件来应用到rails2。0里。

A8 - Insecure Cryptographic Storage

      1.用一个good password .参见:[url]http://www.rorsecurity.info/2007/06/05/use-good-passwords/[/url]

      2.Filter passwords from the log file:

         filter_parameter_logging "password"

         可以参考railscasts第9集.

      3.  清除mysql或bash history可能包含password的地方:

         cat /dev/null > ~/.mysql_history and ~/.bash_history

      4. 永远不要以明文存储密码。

         Signup

         self.salt = Digest::SHA1.hexdigest("–#{Time.now.to_s}–#{login}–")

         self.crypted_password = Digest::SHA1.hexdigest("–#{salt}–#{password}–")

        Login

        self.crypted_password == Digest::SHA1.hexdigest("–#{self.salt}– #{user_entered_password}–")

A9 - Insecure Communications

不 安全通信,解决这个问题需要用SSL来保护一些敏感的数据。IE 7.0 provides a green bar for high trust SSL certificates,but this is not a suitable control to prove safe use of cryptography alone.  所以企业里用IE一般是不安全的。在安全这方面,我们可以说服企业用户去用firefox

1。采用SSL保护敏感数据。

2。确保这些基础设施之间的通信,比如数据库和web servers之间的通信,是建立在一个安全的传输层或是一个有高度加密的信用协议的基础上。

3。必须遵循PCI 安全标准。比如你需要保护信用卡持有者的信息。

具体,这些敏感的数据是不能保存到数据库的。要保存也需要经过加密以后保存。

Ruby打开ssl

http = Net::HTTP.new(PANEL,PORT)

http.use_ssl = true

http.verify_mode = OpenSSL::SSL::VERIFY_NONE

请参考PCI安全标准。

A10 - Failure to Restrict URL Access

一般来说加上异常处理,权限设置就很安全了.

  权限插件使用的安全考证

    目前有好多权限插件,比如LoginGenerator和      Restful_authentication

     但是我们使用前最好考证一下这些插件的安全性,可以去参考这个站点:

     [url]http://www.rorsecurity.info/[/url]

具体待补充。

A11-  其他安全隐患及解决办法:

Validation

一般放到model里,有时候需要放到controller的话,可能你需要一个插件:ActiveForm plugin

Regular Expressions

参见

[url]http://www.rorsecurity.info/2007/04/16/ruby-regular-expression-fun/[/url]

Securing your MySQL setup

Web application security depends on the security of all layers. Start securing your MySQL setup here, then go on here.

here: [url]http://www.rorsecurity.info/2007/02/25/securing-mysql/[/url]

go on here:[url]http://www.rorsecurity.info/2007/02/27/rails%e2%80%99-friends-securing-mysql-continued/[/url]

The mass-assignment problem

When @user = User.new(params[:user]) may become a problem. Read it here:

[url]http://manuals.rubyonrails.com/read/chapter/47[/url]

   黑客可以在网络中通过多种方式攻击、入侵用户的终端,其中最常见,也是用户最容易重招的也正是通过Web站点的间接入侵,作为网络管理员,能够保护企业内网中用户的上网安全是职责所在,我们可以通过安全网关、防病毒墙等产品对网络中数据的通信进行统一管理,也可以结合在终端安装像上网无忧电子眼这种工具来进行防护的方式来实现终端的安全。上网无忧电子眼是趋势科技推出的免费Web威胁防御工具,通过特有的Web信誉服务与僵尸防御功能,能够有效的抵御来自网络的侵袭,使企业用户能够对自身的终端做到合理的防护,从而杜绝僵尸程序、广播病毒等威胁的扩散传播,有效的营造了安全的企业网络环境。

参考:

  [url]http://www.tutorialized.com/view/tutorial/Ruby-on-Rails-Security-cheatsheet/29267[/url]

  [url]http://www.rorsecurity.info/2007/04/15/session-fixation-in-rails/[/url]

  [url]http://weblog.rubyonrails.org/2007/9/30/rails-2-0-0-preview-release[/url]

  [url]http://www.quarkruby.com/2007/9/20/ruby-on-rails-security-guide[/url]

  [url]http://www.owasp.org/index.php/Top_10_2007[/url]

 

©著作权归作者所有:来自51CTO博客作者blackanger的原创作品,如需转载,请注明出处,否则将追究法律责任

安全rails休闲


0人推荐
随时随地看视频
慕课网APP