瞎扯淡 黑客可否修改本地的 cookies 或者 session?

QueXuQ · 2013年11月26日 · 最后由 kgtonglousy 回复于 2014年02月13日 · 16732 次阅读
本帖已被设为精华帖!

黑客可否修改本地的 cookies 或者 session?

如果可以修改,那不就可以伪造一个 cookies 或者 session 来进行登录了?

例如一般判断有没有登录的写法:

User.find(session[:user_id]) if session[:user_id].present?

这样岂不是很不安全?

session 是加密过的,需要拿到 config / initializers / secret_token.rb 里面的密钥才能伪造,所以使用开源项目一定要改这个密钥。

另外还可以窃听网络截获别人的 cookie,为了预防这种攻击要用 SSL。

#1 楼 @Rei 哦。原来是这样的,那请问 cookies 呢?也是和 session 的密钥一样加密过的吗?

#2 楼 @QueXuQ cookie 没加密。

#3 楼 @Rei 哦。就是说如果把东西存在 cookies 里的话,就是不安全的了,别人可以直接伪造和修改了?

把 user_id 存在 session 里,怎么实现 “记住我” 这样的功能,好像每个 session 实例没有单独的有效期属性

#6 楼 @luikore 我想知道 httponly 这玩意怎么加上的?加上 httponly 后,cookies 也安全了? 要确保 cookies 安全,也必须使用 https 了吧?

#8 楼 @QueXuQ

cookies['foo'] = {value: 'bar', httponly: true, secure: true}

加上以后可以减少被第三方篡改的机会, 但 -- 不是用来防用户自己篡改的

#9 楼 @luikore

cookies.signed[:user_preference] = @current_user.preferences

Rails 自带的 signed 呢?会比httponly: true, secure: true好吗?

#10 楼 @QueXuQ signed 可以认为是用来防用户自己篡改的... 例如用户把 session 中的 user_id 改成管理员的 id, 没有签名验证的话就能随便删贴了

#11 楼 @luikore 那最安全策略是:

cookies.signed['foo'] = {value: 'bar', httponly: true, secure: true}

这样子吗?

#12 楼 @QueXuQ 在配置文件里设置config.force_ssl = true试试? 注释写的是Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.

#14 楼 @046569 就是说,开了这个后,cookies 也加密了?

#15 楼 @QueXuQ 安全跟加密不是一个概念。

#15 楼 @QueXuQ 开了 SSL,就无法窃听 cookies,而 httponly 和 secure 是防止第 3 方 js 和非加密请求泄露 cookies 的。这个 cookies 安全了,但是没对用户加密,用户可以操作浏览器改。

而如果 cookies 加密了,并不代表它安全,因为没开 SSL 的话,中间人可以窃听 cookies,只要伪装 cookies 就行了,不用解密它的内容。

所以针对你要防的内容,选择对应措施,或者所有手段都用上。

还有两个小小坑:

  • http 中可以覆写 https 的同名 cookie, 不过有签名校验还好
  • 二级子域名中可以设置主站 cookie, 这个由于有签名校验一般没大碍, 但有时也挺烦人的 (例如个人博客添加了修改 cookie 的 js, 把主站 session 清空了)... 所以 github 把静态站域名改成了 github.io, logdown.com 把登录页面改成 logdown.in

#17 楼 @Rei 那只开 ssl,不对 cookie 加密岂不也可以?

#19 楼 @xautjzd 看你要防的是什么,签名已经拒绝用户自己修改 session 了,加密就更安全

#19 楼 @xautjzd 看错,是说 cookies,不加密就可以随便改

#21 楼 @Rei 加了 secure,只允许用 SSL 访问,应该就对 cookie 加密了吧。但是还是防止不了中间人注入 js 脚本,来获取并篡改 cookie 内容。而 HttpOny 这一选项刚好又防止了 js 的注入,不允许采用 js 来访问或者获取 cookie。现在还没啥大的开发经验,不知道通常保持身份认证采用 cookie 还是 session 比较多呢 ?

在 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">

如果,你用同一个浏览器打开,不用点击任何,就可以做另外一次转账了。

看到楼上的这句,我就略过后面内容了:

Rails 是通过 CSRF, 来防范类似伪造 cookie 或者 session 的。

#24 楼 @git #25 楼 @alsotang 也就是说不需要怕 cookie 被伪造了?

哦,#25 楼 矫情呢吧,想说我混淆概念因为 Cross-Site Request Forgery,不是 rails 里独有名词,不是解决方案。所以后面理解一定不对,就不用看啦,哈哈,我不介意,个人理解而已

话说,Rails 这个 csrf_meta_tags 使用 jquery-ujs 实现的吧,不加 ujs,或者禁用 javascript,会不会没有 fall back 呢

如果拿到了服务器的 cert, 还是可以解密的。

伪造 cookie 很普遍吧 写采集脚本必须的

session 是可以直接被反解开看里面内容的,所以敏感资料不要放里面,不过要随便伪造 session 没有 secret_token 是不行的,所以在一个开源项目里面 secret_token 别弄 github 上就这个道理。

31楼 已删除
32楼 已删除
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册