`
andyhu1007
  • 浏览: 199311 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Rails每周一题(六): Security Guide(上)

阅读更多

此篇文章总结自:http://guides.rubyonrails.org/security.html


谢谢某同学的提醒。

 

Web应用存在的安全问题包括账号劫持,绕过访问控制,读取或者修改敏感信息或者显示欺诈内容等。通过security guide系列篇让我们一起来看看应该如何正确使用Rails来克服这些问题。

 

在上篇中,主要描述对session的攻击,以及应对方法。

 

首先简单介绍一下session的基本概念和一些普遍攻击方法。

 

 

什么是Session

 

Session是一个保存特定用户信息的哈希,用一个session id来识别不同的session。从服务器端发送到客户端浏览器的每一个响应中,cookie都包含一个session id。

 

在Rails里面通过此种方式保存和获取session哈希内的值:

 

session[:user_id] = @current_user.id 
User.find(session[:user_id]) 
 

一个session id由一个随机字符串的哈希值组。这个随机字符串由当前时间,0和1之间的随机数,Ruby解释器的进程id和一个字符串常量组成。所以基本上不可能暴力破解session id。

 

Session劫持

 

通过盗取用户的session id,可以让攻击者以被盗取用户的名义使用web应用。

 

现在大多数网站所使用的认证方式是form-based认证方式 。所以,只要黑客盗取了用户的session id,它既可以以被盗取用户的名义使用web应用。

 

盗取session id的方式有以下几种:

 

  • 监听非安全网络盗取cookie,比如无线网络。可以通过提供基于SSL的安全连接来避免这个问题。
  • 很多人在公共场合使用了网站之后,忘记登出。所以网站要提供明显的logout功能。
  • 定置用户的session id。


Session使用准则

几条关于使用cookie的准则。

 

     1. 不要在session里面存储大量信息。正确的方式是在数据库里存储对象信息,而在session里只存储id。这不仅会缓解session同步问题,而且在对象结构改变时不需要担心遗留在session里面的数据结构不一致问题。

 

     2. 不要在session里面存储重要数据,以免丢失。特别是当你使用客户端保存session时,要当心被盗问题。(客户端保存session,指的是session在服务器端和客户端之间传输整个session,而不是session id。)

 

Session存储机制

— Rails提供了多种session存储机制,最重要的是ActiveRecordStore和CookieStore。

 

因为性能和可维护性,大多数人选择ActiveRecordStore而不是文件存储。

 

而CookieStore由于在服务器和客户端之间传输整个session,虽然此种方式缓解了服务器的压力,但却有很多限制:

 

1. Cookie有严格的大小控制 -- 4K。

 

2. 因为session信息在客户端以明文形式存储(Base64编码),所以有很大的安全隐患。当然,我们可以通过加密方式来防止信息的盗看。方法很简单,在environment.rb里面加上此句:

 

config.action_controller.session = {  :key => '_app_session',  :secret => '0x0dkfj3927dkc7djdh36rkckdfzsg...' } 
 

要注意的是需使用一个复杂的secret。

 

 

 

 

 

 

 

介绍完session的一些基本概念之后,来让我们来看看几种对session的攻击方法和应对策略。

 

 

CookieStore Session的重放攻击

 

假设我们使用CookieStore来存储session,将会带来这样的安全问题:

 

1. 用户获取信用卡信息,余额存储于session(很差的主意,示范之用。)

2. 用户购买了一些东西。

3. 现在在session里面存储的余额是购买之后扣去购买费用之后的余额。

4. 用户用第一步中的session替换现在的session。

5. 用户的余额被恢复到初始时。

 

我们可以通过nonce 解决这个问题,但nonce需要服务器端数据库的跟踪,所以这已经违背了使用CookieStore避免使用数据库的初衷。

 

所以,问题的关键所在还是在于不应在session里面存储重要信息。

 

Session定置

— 攻击者通过定置其他用户的session id,而非盗取session id的方式来使用其它用户的账户。

 

session fixation

 

 

让我们看看这种攻击是如何发生的:

  1. 攻击者访问网站,并从cookie中获取session。 (见图中第1 和 第2步).
  2. 攻击者通过不断访问网站使session保持不过期。
  3. 攻击者强迫受害者使用他的session id(见图中第3步)。由于不可能更改另一个域的cookie(由于同一来源策略 -- same origin policy ), 攻击者通过在被攻击网站上运行一段如下的JavaScript代码来更改受害者的cookie。JavaScript代码的注入通过XSS的协助完成。
    <script>
document.cookie="_session_id=16d5b78abb28e3d6206b60f22a03c8d9";
</script>.
     
  4. 受害者在浏览被注入恶意代码的网页时被更改了cookie值。
  5. 服务器发现此session id并未登录,就要求受害者重新登录。
  6. 从此刻开始,攻击者和受害者使用的是通过一个session id。而受害者对此一无所知。

 

应对策略:

 

只需要一行代码:

 

reset_session 

 

reset_session会清空旧session里的所有值,并且创建一个新session。在用户登录成功后运行此句,会让session定置攻击失效。不过要注意的是,需要转移旧session中的值到新session。如果你使用的是RestfulAuthentication插件,那么在SessionsController#create 方法中加入此句。

 

还有一种应对方法是在session里面加上一些用户特定的信息,比如IP地址等。但用此种方法得注意IP地址并不一定直接对应到确定的用户,很多用户在proxy后面访问。

 

 

 

Session过期问题

 

 

让session在很长的时间内都不过期,会增大安全隐患。

 

让session过期有两种方式:

 

1. 在客户端:在session id cookie上设置一个过期时间。但用户可以通过修改cookie来改变过期时限。

 

2. 在服务端,我们可以通过如下代码来清除未使用时间超过20分钟的session:

 

class Session < ActiveRecord::Base 






def self.sweep(time_ago = nil) 







time = case time_ago 







when /^(\d+)m$/ then Time.now - $1.to_i.minute 







when /^(\d+)h$/ then Time.now - $1.to_i.hour 







when /^(\d+)d$/ then Time.now - $1.to_i.day 







else Time.now - 1.hour 







end 







self.delete_all "updated_at < '#{time.to_s(:db)}'" 







end







end
 

当然,攻击者可以通过每隔几分钟访问一次网站来保持session,可以加上这一段代码来清除创建时间过久的session:

 

self.delete_all "updated_at < '#{time.to_s(:db)}' OR created_at < '#{2.days.ago.to_s(:db)}'" 

 

 

未完待续,请看Security Guide中篇下篇

 

  • 大小: 46.7 KB
  • 大小: 41 KB
分享到:
评论
5 楼 edokeh 2009-05-07  
rails是不是不能检测到session的过期事件?好像没有类似J2EE里面SessionListener这样的东西
4 楼 andyhu1007 2009-05-06  
wannago 写道

不错。但是翻译别人的文章难道不应该向别人致谢吗?http://www.owasp.org/index.php/Category:OWASP_Ruby_on_Rails_Security_Guide_V2


我写或者说总结一些东西纯粹是为了分享和让自己加深理解的目的。

谢谢提醒。我已经在文章头部加上注明。
3 楼 wannago 2009-05-06  
不错的文章。
2 楼 andyhu1007 2009-05-05  
谢谢被评为精华帖。不过这篇文章并非我全部原创,而是总结自:http://guides.rubyonrails.org/security.html。
1 楼 rubyrock 2009-05-04  
不错的文章!

相关推荐

    Rails的精简版本Rails::API.zip

    Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...

    Rails上的API:使用Rails构建REST APIAPIs on Rails: Building REST APIs with Rails

    在本篇内容中,我们将深入探讨如何利用Ruby on Rails(简称Rails)这一强大的Web应用程序框架来构建可伸缩且易于维护的RESTful API。Rails以其简洁优雅的语法、高效的开发速度以及良好的社区支持而闻名,这使得它...

    Ruby on Rails入门例子

    Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...

    rails-ansible-presentation:有关Rails + Ansible的Deckset演示

    将应用程序放在服务器上。 捆绑宝石。 应用迁移。 重新启动服务。 Easy Rails部署 git push master heroku:master , , , ,其他… 快速简便,但不灵活且昂贵。 您自己的基础架构 更复杂[^ 1],但更灵活且更...

    rails-basic-template:基本 Rails 模板

    Rails 基本模板参考: : Ruby on Rails Gemfile:定义应用程序正在使用的库的文件bundle install:基于Gemfile,安装所有库每次修改 Gemfile 时都应该运行bundle install gem 是 Ruby 的库RubyGems.org 是一个查找和...

    rails-style-guide:社区驱动的Ruby on Rails样式指南

    本指南的目的是为Ruby on Rails 4开发提供一组最佳实践和样式说明。 它是对现有社区驱动的的补充。 本Rails风格指南推荐了最佳实践,以便实际的Rails程序员可以编写可由其他实际的Rails程序员维护的代码。 会使用...

    rails_console_toolkit:可配置的 Rails 控制台助手

    RailsConsole 工具包 :wrench: :toolbox: 可配置的 Rails 控制台助手更快地查找记录,添加自定义助手,将您的控制台寿命提高 100%。安装将此行添加到应用程序的 Gemfile 中: gem 'rails_console_toolkit' 然后生成...

    Ruby On Rails 面试系列七,一个面试练习题

    这个面试练习题可能是为了测试应聘者对于Rails应用的构建、自动化任务管理、测试驱动开发(TDD)以及文件组织结构的理解。让我们逐一探讨这些知识点。 首先,`Rakefile`是Ruby中的构建工具,类似于其他语言的...

    Ruby on Rails入门经典代码

    Ruby on Rails,简称Rails,是基于Ruby语言的一个开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本压缩包中的"Ruby on Rails入门经典代码"提供了新手学习...

    webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成.zip

    webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成 不再维护webpack-rails 不再被维护。 有关详细信息,请参阅 #90. web pack-railsweb pack 为你提供了将 web pack集成到现有的Ruby on Rails 应用程序中...

    rails指南 中文版

    Rails指南中文版是针对Ruby on Rails框架的一份详尽教程,旨在帮助开发者深入理解并熟练掌握这个强大的Web应用开发工具。Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-...

    rails_email_preview:在Rails中预览和编辑应用程序邮件模板

    安装加 到Gemfile: gem 'rails_email_preview' , '~&gt; 2.2.2' 添加一个初始化程序和路由: $ rails g rails_email_preview:install 在app / mailer_previews /中生成预览类和方法存根$ rails g rails_email_preview:...

    rails-developer-scanning:针对Rails开发人员的自动面试问题

    标题 "rails-developer-scanning" 指向的是一个针对Rails开发者设计的自动化面试工具,旨在帮助面试官或招聘者快速有效地评估应聘者的Rails技能。这个工具名为 "jyaasa_interviewer",通过RubyGem安装,使得面试过程...

    rails-guide-blog:为了刷新我对Ruby on Rails的了解,我正在从https建立这个博客

    自述文件这是刷新经验的一种方法。 《 Rails指南》中的当前步骤: : 与在控制器和视图之间传递数据的典型方式相反(直接使用实例变量),我将使用控制器中定义的属性访问器方法,以减少由于实例变量名称的拼写错误而...

    rails-dom-testing:从ActionView中提取DomAssertions和SelectorAssertions

    Rails :: Dom :: Testing 这个gem负责比较HTML DOM并断言Rails应用程序中存在DOM元素。 assert_dom_equal通过assert_dom_equal和assert_dom_not_equal进行比较。 元素通过assert_dom , assert_dom_encoded , ...

    rails-docker-compose:Ruby on Rails的Docker开发环境

    一个易于安装的依赖关系可在新计算机上进行编码:Docker。 (与使用Vagrant时的两个复杂的比较。) 面向开发的配置:装入源代码,以便容器中的更改出现在主机上,反之亦然。 快速重建,因为DOCKERFILE是为帮助...

    Rails中应用Ext.tree:以中国的省市地区三级联动选择为例

    这篇博客文章“Rails中应用Ext.tree:以中国的省市地区三级联动选择为例”提供了一个实用的示例,教我们如何利用Ext.js库中的Tree组件来实现这种功能。 首先,让我们了解Rails和Ext.js的基本概念。Rails是基于Ruby...

    rails-controller-testing:将`assigns`和`assert_template`带回到您的Rails测试中

    Rails :: Controller :: Testing 这个gem将assigns给控制器测试的内容以及assert_template带回assigns控制器和集成测试的内容。 这些方法已中。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-...

    rails-html-sanitizer

    如果您在非Rails应用程序中需要类似的功能,请考虑直接使用(这是处理内幕消毒的原因)。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-html-sanitizer' 然后执行: $ bundle 或将其自己安装为: $...

    Rails相关电子书汇总

    Ruby on Rails,通常简称为Rails,是一个基于Ruby语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,以简洁、高效的代码和“约定优于配置”的理念著称。此压缩包中的"rubyonrails21-cn.pdf"可能是...

Global site tag (gtag.js) - Google Analytics