上篇
中介绍了对session的攻击方法以及应对策略,在此篇继续介绍其它一些对网站的攻击方法以及应对策略。在阅读本文的过程中,你会发现,其实避免很多安全问题并不困难。只是很多时候,我们并没有把安全问题这个概念放在心里。
跨站请求伪造
(CSRF
)
跨站请求伪造在网页上注入恶意代码或者一些恶意链接,来访问用户已被认证的网站。如果session未过期,攻击者就可以进行一些恶意的操作。
我们知道在用户访问网站时,cookie里面都会带有session id。而有争议的一点是,当这个请求来自另外一个域时,session id也会被附在cookie上。
让我们来看看一个攻击的例子:
1. Bob浏览一张被黑客恶意改造过的网页,此网页有一个image element,但是此element并不指向一张图片,而是链接至Bob的项目管理站点:
<img src="http://www.webapp.com/project/1/destroy">
2. 假设此时Bob在www.webapp.com上的session仍然有效。
3. 当Bob浏览此页面时,它会试图从www.webapp.com导入图片。同时,会附带发送带有正确session id的cookie。
4. www.webapp.com确认了用户信息,并执行了相应操作。
5. 图片未显示,同时Bob也未注意到任何攻击的发生。
应对策略:
1. 适当使用GET和POST。当操作会对数据状态进行更改,或者用户需要对操作负责时,使用POST请求。当然,在RESTful下,还有PUT和DELETE请求。通过正确应用HTTP verbs,可以避免上述问题的出现。
在Rails里面,可以通过在controller里面增加类似代码:
verify :method => :post, :only => [:transfer], :redirect_to => {:action => :list}
但是黑客还是可以通过更加复杂的攻击方法来绕过这个限制,比如:
<a href="http://www.harmless.com/" onclick=" var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = 'http://www.example.com/account/destroy'; f.submit(); return false;">To the harmless survey</a>
2. 上面问题的解决方法是通过在所有非GET请求中包含一个security token -- 在服务器端会检查此security token。在Rails2.0以及后来的版本中,只要在application controller里面加入如下一行即可:
protect_from_forgery :secret => "123456789012345678901234567890..."
加入这行后,Rails会在所有由Rails生成的form和Ajax请求中
包含security token,这个security token通过当前session和服务端的secret计算而得。如果security
token验证没有通过,会抛出ActionController::InvalidAuthenticityToken异常。(注意,在使用
CookieStore session存储机制时,不需要secret。)
重定向
— 重定向至陷阱网站。
假如我们的controller中有这样一个action:
def legacy
redirect_to(params.update(:action=>'main'))
end
这个action是一个遗留action,它现在做的工作只是把对它的访问转向到main action。
此时,如果攻击者用这样一个url对此action发起请求。
http://www.example.com/site/legacy?param1=xy¶m2=23&host=www.attacker.com
那么legacy action会把请求重定向至www.attacker.com。请注意url最后的host参数。
应对策略:
通过一个白名单(白名单,而不是黑名单)对legacy action的参数进行过滤。
文件相关攻击
文件上传
— 不要让上传文件覆盖重要文件,并且注意异步处理媒体文件。
假设我们把上传文件存于目录“/var/www/uploads",然后用户上传了一个名字叫做“../../../etc/passwd”的文件。
那么passwd文件就有被覆盖的危险。(当然,Ruby解释器需要有相应的权限进行此操作才可以。从这里看出让web server,数据库等其他一些程序在一个低权限的用户上跑是多么重要。)
应对策略:
对文件名进行验证。参考attachment_fu plugin
的例子:
def sanitize_filename(filename)
returning filename.strip do |name|
# NOTE: File.basename doesn't work right with Windows paths on Unix
# get only the filename, not the whole path
name.gsub! /^.*(\\|\/)/, ''
# Finally, replace all non alphanumeric, underscore
# or periods with underscore
name.gsub! /[^\w\.\-]/, '_'
end
end
拒绝服务
同步处理上传文件的一个很大的缺点在于它使网站易于被拒绝服务
所攻击。假如攻击者同时上传很多文件,服务器可能会被拖垮。
应对策略:
异步处理上传文件。在服务器端保存文件后,在后台安排一个进程对文件进行处理。
上传可执行文件
— 不要把上传文件置于Rails的public目录下 -- 如果这个目录是Apache的home目录。
Apache Web服务器有个特点,就是它会执行DocumentRoot目录下的有特定扩展名的文件,比如PHP和CGI文件。假设攻击者上传了一个file.cgi文件,那么当他下载这个文件时,这个文件就会被执行。
应对策略:
如果Rails的public目录是Apache的home目录,就不要在此目录下存储上传文件。至少把文件存于下一级目录。
文件下载
— 不要让用户下载任意文件。
send_file('/var/www/uploads/' + params[:filename])
上面这段代码可以让用户下载任意文件。假如用户输入的文件名是 “../../../etc/passwd”,那么passwd文件就会被下载。
应对策略:
验证被下载文件在合法的目录下
basename = File.expand_path(File.join(File.dirname(__FILE__), '../../files'))
filename = File.expand_path(File.join(basename, @file.public_filename))
raise if basename =! File.expand_path(File.join(File.dirname(filename), '../../../'))
send_file filename, :disposition => 'inline'
管理员站点的安全问题
— Admin Site具有一些超权限,所以经常成为黑客的攻击目标。对于Admin Site,要采取一些额外的安全策略。
1. 为了防止Admin Site受到XSS的攻击,建议使用Safe ERB
插件阻止用户恶意代码的注入。
2. 如果做最坏的打算 -- 管理员的用户名和密码真的被盗了。那么我们可以采取什么措施防护?比如让一些特权操作需要一些特殊的密码。
3. 管理站点真的需要在任何地方都可以被访问么?限制管理站点只能从来自一些特殊IP的访问。
4. 把管理站点置于子域比如admin.webapp.com或者一个独立域,可以防止XSS的攻击。(相同来源策略)
Mass Assignment
— 如果不做一些预防措施,Modle.new(params[:model])允许攻击者设置任何数据库字段的值。
假设在注册时用户传上来的参数是这样的:
params[:user] #=> {:name => “ow3ned”, :admin => true}
那么当程序处理时,会把这个用户置为一个admin用户。
应对策略:
保护一些字段,防止它被Mass Assignment:
attr_protected :admin
但这是一个黑名单,如果你新加了一个受保护字段,必须不能忘记在列表上添加上。所以更好的方法是:
attr_accessible :name
字段受保护之后,你只能给它单独赋值:
params[:user] #=> {:name => "ow3ned", :admin => true}
@user = User.new(params[:user])
@user.admin #=> false # not mass-assigned
@user.admin = true
@user.admin #=> true
更绝对的一种做法是,在初始的时候加上这么一句:
ActiveRecord::Base.send(:attr_accessible, nil)
它会把所有model的白名单置空,你必须对每个model显示地指定attr_accessible名单。
帐户管理
restful_authentication插件的安全漏洞
假如我们使用了restful_authentication的激活策略:每个新注册用户都会收到一个激活链接,当访问了激活链接后,数据库里的激活码字段会被置为null。
激活链接例子:
http://localhost:3006/user/activate?id=xrfqlki3453325xdgl
程序处理:
User.find_by_activation_code(params[:id])
假如用户用这样URL访问:
http://localhost:3006/user/activate
http://localhost:3006/user/activate?id=
那么生成的sql就变成这样了:
SELECT * FROM users WHERE (users.activation_code IS NULL) LIMIT 1
它会找到第一个已经被激活的用户。
账户的暴力破解
有些黑客采取暴力破解的方式来获取账号,而有时候我们的网站的一些小问题却帮了他们的忙。
我们可能在提示信息里面提供任何对黑客有用的信息,比如有些网站在用户输入正确用户名和错误密码时会提示:Your password is invalid,或者在用户名未找到时提示:the user name you entered has not been found。
应对策略:
正确的做法是只要用户提供的用户名和密码无法登陆,则提供提示信息:user name or password not correct。
同时,在发现来自同一个IP的多次失败登录行为之后,需让用户输入验证码进行登录。
账户劫持
1. 修改密码时要阻止CSRF的攻击。
2. 修改email地址或者进行其它一些操作时,需让用户提供密码。
日志
日志很多时候成为了一个很大的安全隐患,虽然在数据库里我们对密码进行了加密,但在日志里是明文。
应对策略:
在controller里面加上一行以阻止密码被日志所记录。
filter_parameter_logging :password
正则表达式
— 注意^ $ 和 \A \z的区别。
比如我们用这样一个验证:
class File < ActiveRecord::Base
validates_format_of :name, :with => /^[\w\.\-\+]+$/
end
那么当用户输入如下文件名时,能很容易地绕过这个验证:
file.txt%0A<script>alert('hello')</script>
它会被URL解码为“file.txt\n<script>alert(‘hello’)</script>”。
这里的问题在于Ruby里面的正则表达式中^和$匹配的是行首和行尾
。
应对策略
:
正确的做法应该是:
/\A[\w\.\-\+]+\z/
权限放大
这个问题貌似是我们经常会忽略的问题。
比如有这样的句子:
@project = Project.find(params[:id])
那么当用户改变了一个参数之后,他就可以访问其它用户的信息。
应对策略:
@project = @current_user.projects.find(params[:id])
中篇完结。在本篇中,介绍了一些在创建程序的过程中,我们要注意的一些小问题。这些东西其实都不复杂,但如果我们忽视了,则会引起很大的安全问题。
待续,下篇
关于多种注入的威胁,比如sql注入,css注入等。
分享到:
- 2009-05-03 13:50
- 浏览 2076
- 评论(0)
- 论坛回复 / 浏览 (0 / 3022)
- 查看更多
相关推荐
Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...
这个面试练习题可能是为了测试应聘者对于Rails应用的构建、自动化任务管理、测试驱动开发(TDD)以及文件组织结构的理解。让我们逐一探讨这些知识点。 首先,`Rakefile`是Ruby中的构建工具,类似于其他语言的...
在本篇内容中,我们将深入探讨如何利用Ruby on Rails(简称Rails)这一强大的Web应用程序框架来构建可伸缩且易于维护的RESTful API。Rails以其简洁优雅的语法、高效的开发速度以及良好的社区支持而闻名,这使得它...
Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...
Rails指南中文版是针对Ruby on Rails框架的一份详尽教程,旨在帮助开发者深入理解并熟练掌握这个强大的Web应用开发工具。Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-...
安装加 到Gemfile: gem 'rails_email_preview' , '~> 2.2.2' 添加一个初始化程序和路由: $ rails g rails_email_preview:install 在app / mailer_previews /中生成预览类和方法存根$ rails g rails_email_preview:...
Rails 基本模板参考: : Ruby on Rails Gemfile:定义应用程序正在使用的库的文件bundle install:基于Gemfile,安装所有库每次修改 Gemfile 时都应该运行bundle install gem 是 Ruby 的库RubyGems.org 是一个查找和...
[适合] Rails :red_heart: Ansible [适合] Rails :red_heart: Ansible (有一点帮助) Rails部署 简单吧? 将应用程序放在服务器上。 捆绑宝石。 应用迁移。 重新启动服务。 Easy Rails部署 git push master ...
本指南的目的是为Ruby on Rails 4开发提供一组最佳实践和样式说明。 它是对现有社区驱动的的补充。 本Rails风格指南推荐了最佳实践,以便实际的Rails程序员可以编写可由其他实际的Rails程序员维护的代码。 会使用...
通过学习和实践压缩包中的"Ruby on Rails入门经典代码",新手不仅可以了解Rails的基本概念,还能掌握实际项目中的应用技巧,逐步成长为一名熟练的Rails开发者。记得不断探索、实践和学习新的Rails知识,以适应不断...
安装将此行添加到应用程序的 Gemfile 中: gem 'rails_console_toolkit' 然后生成初始化程序: $ bin/rails generate rails_console_toolkit:install或手动编写: # config/initializers/console....
webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成 不再维护webpack-rails 不再被维护。... web pack-railsweb pack 为你提供了将 web pack集成到现有的Ruby on Rails 应用程序中的工具。它很乐
Rails :: Dom :: Testing 这个gem负责比较HTML DOM并断言Rails应用程序中存在DOM元素。 assert_dom_equal通过assert_dom_equal和assert_dom_not_equal进行比较。 元素通过assert_dom , assert_dom_encoded , ...
这篇博客文章“Rails中应用Ext.tree:以中国的省市地区三级联动选择为例”提供了一个实用的示例,教我们如何利用Ext.js库中的Tree组件来实现这种功能。 首先,让我们了解Rails和Ext.js的基本概念。Rails是基于Ruby...
《 Rails指南》中的当前步骤: : 与在控制器和视图之间传递数据的典型方式相反(直接使用实例变量),我将使用控制器中定义的属性访问器方法,以减少由于实例变量名称的拼写错误而导致NoMethodError出现nil的可能性...
标题 "rails-developer-scanning" 指向的是一个针对Rails开发者设计的自动化面试工具,旨在帮助面试官或招聘者快速有效地评估应聘者的Rails技能。这个工具名为 "jyaasa_interviewer",通过RubyGem安装,使得面试过程...
Rails :: Controller :: Testing 这个gem将assigns给控制器测试的内容以及assert_template带回assigns控制器和集成测试的内容。 这些方法已中。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-...
允许您使用为Rails应用程序的前端供电。 是将前端工具像Ruby一样进行编程,纯属喜悦! :smiling_face_with_heart-eyes: 或在运行的检查。 产品特点 :high_voltage: :light_bulb: 即时服务器启动 :high_voltage: ...
在Ruby on Rails框架中,命令行工具是开发者日常工作中不可或缺的一部分。Rails命令允许我们快速地构建应用程序、管理数据库、生成代码以及执行各种自动化任务。以下是一些关键的Rails命令及其详细解释: 1. **创建...
如果您在非Rails应用程序中需要类似的功能,请考虑直接使用(这是处理内幕消毒的原因)。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-html-sanitizer' 然后执行: $ bundle 或将其自己安装为: $...