cookie的安全隐患以及防篡改机制
一、cookie的认识
- cookie
1)cookie是指某些网站为了辨别用户身份、进行session跟踪而存储在用户本地终端上的数据(通常经过加密) - cookie的登录
1)排除用户手动删除浏览器cookie以及cookie未过期的情况下,用户如果在某网站登录过一次,下次访问这个网站,用户不需要输入用户名和密码就可以进入网站 - cookie的生命周期
1)创建cookie的时候,会给cookie指定一个值:Expire,它就是指定cookie的有效期,也就是cookie的生命周期,超出设置的这个生命周期,cookie就会被清除
2)如果给这个值Expire设置为0或者负值,那么这样的设置就是在关闭浏览器时,就会清除cookie,这种方式更加安全 - session 与 cookies的不同
1)存储位置不同
session在服务器端产生,比较安全,但是如果session较多则会影响性能
cookies在客户端产生,安全性稍弱
2)声明周期不同
session生命周期 在指定的时间(如20分钟)到了之后会结束,不到指定的时间,也会随着浏览器进程的结束而结束
cookies默认情况下也随着浏览器进程结束而结束,但如果手动指定时间,则不受浏览器进程结束的影响
3)信息存储时效不同
使用session保存用户信息,用户信息往往会丢失而重新登录
使用cookies保存用户信息,用户信息可以长时间有效
二、cookie的安全隐患
- cookie的不安全
1)HTTP协议是无状态的,即每次用户请求到达服务器时,HTTP服务器并不知道这个用户是谁、是否登录过等。浏览器之所以能够知道我们是否登录,是因为服务器在登录时设置了浏览器的cookie,session则是借由cookie而实现的更高层的服务器与浏览器之间的会话
2)cookie存储在浏览器端,也就是用户本地,通过浏览器能截获cookie,比如脚本、利用工具抓取等
3)cookie标识用户登录状态:
a. 用户提交用户名和密码的表单,这通常是一个POST HTTP请求
b. 服务器验证用户名与密码,如果合法则返回200(OK)并设置 Set-Cookie 为 authed=true
c. 浏览器存储该Cookie
d. 浏览器发送请求时,设置Cookie字段为 authed=true
e. 服务器收到第二次请求,从Cookie字段得知该用户已经登录, 按照已登录用户的权限来处理此次请求
4)发送HTTP请求的不只是浏览器,很多HTTP客户端软件(包括curl、Node.js)都可以发送任意的HTTP请求,可以设置任何头字段。 假如我们直接设置cookie字段为authed=true并发送该HTTP请求,服务器就会被欺骗,这种攻击对于cookie来说很容易被篡改
2.cookie的不安全表现
1)cookie欺骗
不需要知道这个cookie的具体含义,只需要将这个cookie向服务器提交(模拟身份验证),身份验证通过之后,就可以冒充被窃取cookie对应用户来访问网站,甚至获取到用户的隐私信息,对于用户的隐私造成非常严重的危害
2)cookie截获
cookie以纯文本的形式在浏览器和服务器之间传递,在web通信时极容易被非法用户截获和利用。非法用户截获cookie后,在cookie的有效时间内重新发放给服务器,那么这个非法用户就拥有了这个合法用户的所有权限
3)Flash的内部代码隐患
Flash内部中有一个getURL()函数,Flash可以利用它自动打开指定的页面。在观看Flash时,可以打开一个特殊操作的页面,可以是木马,可以向远端输入当前cookie或者用户信息,同时这个是Flash内部的操作,所以网站无法禁止,这个是非常危险的
三、cookie的防篡改机制以及安全解决
- cookie的防篡改机制
1)服务器可以为每个cookie项生成签名,由于用户篡改cookie后无法生成对应的签名, 服务器便可以得知用户对cookie进行了篡改
2)校验过程
在服务器中配置一个不为人知的字符串(我们叫它Secret),比如:x$sfz32
当服务器需要设置Cookie时(比如authed=false
),不仅设置authed的值为false, 在值的后面进一步设置一个签名,最终设置的Cookie是authed=false|6hTiBl7lVpd1P
签名6hTiBl7lVpd1P
是这样生成的:Hash('x$sfz32'+'false')
。 要设置的值与Secret相加再取哈希用户收到HTTP响应并发现头字段Set-Cookie: authed=false|6hTiBl7lVpd1P
用户在发送HTTP请求时,篡改了authed值,设置头字段Cookie: authed=true|???
。 因为用户不知道Secret,无法生成签名,只能随便填一个服务器收到HTTP请求,发现Cookie: authed=true|???
。服务器开始进行校验:Hash('true'+'x$sfz32')
,便会发现用户提供的签名不正确
3)cookie是明文传输的,只要服务器设置过一次authed,就可以用这个签名欺骗服务器。在cookie当中,不要存放敏感数据,cookie一般只存放一个session Id,而session 一般存储在服务器端 - cookie的安全解决
1)设置cookie有效期不要过长,合适即可
2)设置HttpOnly属性为true
可以防止js脚本读取cookie信息,有效的防止XSS攻击
3)设置复杂的cookie,加密cookie
cookie的key使用uuid,随机生成
cookie的value可以使用复杂组合,比如:用户名+当前时间+cookie有效时间+随机数
4)用户第一次登录时,保存ip+cookie加密后的token
每次请求,都去将当前cookie和ip组合起来加密后的token与保存的token作对比,只有完全对应才能验证成功
5)session和cookie同时使用
session Id虽然放在cookie中,但是相对的session更安全,可以将相对重要的信息存入session
6)如果网站支持https,尽可能使用https
如果支持https,为cookie设置Secure属性为true,这样cookie只能使用https协议发送给服务器,而https比http更加安全
还没有评论,来说两句吧...