黑客可否修改本地的 cookies 或者 session?
如果可以修改,那不就可以伪造一个 cookies 或者 session 来进行登录了?
例如一般判断有没有登录的写法:
User.find(session[:user_id]) if session[:user_id].present?
这样岂不是很不安全?
session 是加密过的,需要拿到 config / initializers / secret_token.rb 里面的密钥才能伪造,所以使用开源项目一定要改这个密钥。
另外还可以窃听网络截获别人的 cookie,为了预防这种攻击要用 SSL。
最好给 cookie 和 session 对应的 cookie 加上 httponly 的选项,防止 javascript 访问。(用户用了奇怪的浏览器,或者装了奇怪的浏览器插件都可能让注入的 javascript 盗取 session)
用 ssl 就必须在 cookie 加上 secure 选项,因为在 http 访问同域名的时候,同域名的 cookie 会被明文发送,就没起到 ssl 加密的效果了。secure 选项可以保证只在 https 的时候才发送这个 cookie.
错误的 cookie 示例 (这个站点的 cookie 的 http 和 secure 栏都是空的 - 安全隐患):
正确的 cookie 示例
cookies['foo'] = {value: 'bar', httponly: true, secure: true}
加上以后可以减少被第三方篡改的机会,但 -- 不是用来防用户自己篡改的
cookies.signed[:user_preference] = @current_user.preferences
Rails 自带的 signed 呢?会比httponly: true, secure: true
好吗?
还有两个小小坑:
在 cookie 中不记录密码,只记录 token,用 token 授权 0.登录时,token 赋初值 1.超过 30 分钟,token 失效 2.每一次用户请求,token 重置 3.记录用户常用 IP 和登录设备 4.危险操作采用短信或者邮箱多重验证 这样应该相对安全一些
如果,你用的是 rails 的话,并且按照规矩正常使用的话。不用 ssl 也已经防范了
Rails 是通过 CSRF, 来防范类似伪造 cookie 或者 session 的。
办法就是,
服务器端:
在 application controller 里放
protect_from_forgery
用来检查请求是不是来自,自己服务器生成的表单
客户端: 在 view 里放
csrf_meta_tags
这个呢,会生成一个 csrf-params 一个 csrf-token, 用来发回到服务器验证
# File actionpack/lib/action_view/helpers/csrf_helper.rb, line 7
def csrf_meta_tag
if protect_against_forgery?
%(<meta name="csrf-param" content="#{Rack::Utils.escape_html(request_forgery_protection_token)}"/>
<meta name="csrf-token" content="#{Rack::Utils.escape_html(form_authenticity_token)}"/>).html_safe
end
end
那么一般情况下,我们用form_for
或者表单 tag 的时候,这个 csrf 都是自己生成的,都不用担心。服务器端验证也是默认的。
例外的情况是,json api + ajax 请求,要自己注意验证,是不是伪造请求。
protect_from_forgery 可以加参数,就说检查到伪造请求,可以清除 session 或者,产生异常详见
通常情况说的 CSRF 跨站伪造请求的例子是。
你刚刚登录你的银行,做了一笔转账。
收到一个邮件,里面有个图片,
<imgsrc="http://bank.com/transfer.do?acct=MARIA&amount=100000"width="1" height="1" border="0">
如果,你用同一个浏览器打开,不用点击任何,就可以做另外一次转账了。
哦,#25 楼 矫情呢吧,想说我混淆概念因为 Cross-Site Request Forgery,不是 rails 里独有名词,不是解决方案。所以后面理解一定不对,就不用看啦,哈哈,我不介意,个人理解而已
话说,Rails 这个
csrf_meta_tags
使用 jquery-ujs 实现的吧,不加 ujs,或者禁用 javascript,会不会没有 fall back 呢
session 是可以直接被反解开看里面内容的,所以敏感资料不要放里面,不过要随便伪造 session 没有 secret_token 是不行的,所以在一个开源项目里面 secret_token 别弄 github 上就这个道理。