cookie保存类似于"受理编号"的会话ID。
cookie的使用,类似于银行柜台申请服务。
顾客:你好。
柜员:您的受理编号为005。请提供你的银行卡号和密码。
顾客:受理编号为005。卡号为12345,密码为9876,请确认。
柜员:身份核实完毕。
顾客:受理编号为005。请帮我查一下余额。
柜员:余额为5万元。
顾客:受理编号为005。请向卡号23456的账号转账3万元。
柜员:转账完毕。
这里还是有一个问题,如果cookie值真像上面这么简单的数字,是一个很容易猜到的值,那么一个恶意的顾客,就可以猜出顾客的受理编号,从而伪装成客户进行一些恶意操作。比如:
恶人:你好。
柜员:您的受理编号为006。请提供您的银行卡和密码。
这是恶人将受理编号减一变为005。假设受理编号为005的客户已经通过了身份核实。
恶人:受理编号为005。请向卡号99999的账户转账3万元
柜员:转账完毕
由此可见,会话ID不能使用连续数字,应当使用位数足够长的随机数。
综上,会话ID需要满足如下需求:
- 会话ID不能被第三方推测。
- 会话ID不能被第三方劫持
- 会话ID不能像第三方泄露
需求1本质上要求是随机数的质量问题。
防御方案:
会话ID也并非手动生成的,应该使用web应用开发工具提供的会话ID。务必不要自己来实现会话管理机制。
需求2不能被劫持。会话劫持又分两种情况,一种叫做会话劫持,一种叫做会话固定。
-
会话劫持
一种通过获取用户ID后,使用该ID登陆目标账号的攻击方式,此时攻击者实际上是使用了目标账户的有效ID。会话劫持的第一步是取得一个合法的会话表示来伪装成合法的用户。
银行的例子来说明:
顾客拿到了受理编号33851045d2bc44564b5ee17f6bb3db7,恶人用一种方式获取到了顾客的这个编号。如果用户已经登陆成功
恶人:受理编号为33851045d2bc44564b5ee17f6bb3db7。请向卡号99999的账户转账3万元。 柜员:转账完毕
防御方案:
1、 更改Session名称。PHP中Session的默认名称是PHPSESSID,此变量会保存在Cookie中,如果攻击者不分析站点,就不能猜到Session名称,阻挡部分攻击。
2、 关闭透明化Session ID。透明化Session ID指当浏览器中的Http请求没有使用Cookie来存放Session ID时,Session ID则使用URL来传递。
3、 设置HttpOnly。通过设置Cookie的HttpOnly为true,可以防止客户端脚本访问这个Cookie,从而有效的防止XSS攻击。
4、 关闭所有phpinfo类dump request信息的页面。
5、 使用User-Agent检测请求的一致性。但有专家警告不要依赖于检查User-Agent的一致性。这是因为服务器群集中的HTTP代理服务器会对User-Agent进行编辑,而本群集中的多个代理服务器在编辑该值时可能会不一致。
6、 加入Token校验。同样是用于检测请求的一致性,给攻击者制造一些麻烦,使攻击者即使获取了Session ID,也无法进行破坏,能够减少对系统造成的损失。但Token需要存放在客户端,如果攻击者有办法获取到Session ID,那么也同样可以获取到Token。
-
会话固定
会话固定是一种诱骗受害者使用攻击者制定的会话标识的攻击手段。
恶人:你好 柜员:您的受理编号为9466ir8fgmmk1gn7raeo7ne71。请提供您的银行卡号和密码。 恶人暂时离开回台等待来客。有顾客进入银行时,恶人冒充银行柜员向客户搭话。 恶人:您的受理编号为9466ir8fgmmk1gn7raeo7ne71。 顾客:我知道了。 顾客走向柜台。 顾客:我的受理编号为9466ir8fgmmk1gn7raeo7ne71。 柜员:请提供您的银行卡号和密码。 顾客:受理编号为9466ir8fgmmk1gn7raeo7ne71。卡号为12345,密码为9876,请确认。 柜员:身份核实完毕。 顾客执行完身份确认之后也走向柜台。 恶人:受理编号为9466ir8fgmmk1gn7raeo7ne71。请向卡号99999的账号转账3万元。 柜员:转账完毕。
防御方法:
1、每当用户登陆的时候就进行重置sessionID
2、sessionID闲置过久时,进行重置sessionID
3、 大部分防止会话劫持的方法对会话固定攻击同样有效。如设置HttpOnly,关闭透明化Session ID,User-Agent验证,Token校验等。
【多个方法结合使用】
这里使用方法2举一个简单的例子:
有顾客进入银行时,恶人冒充银行柜员向客户搭话。 恶人:您的受理编号为9466ir8fgmmk1gn7raeo7ne71。 顾客:我知道了。 顾客走向柜台。 顾客:我的受理编号为9466ir8fgmmk1gn7raeo7ne71。 柜员:请提供您的银行卡号和密码。 顾客:受理编号为9466ir8fgmmk1gn7raeo7ne71。卡号为12345,密码为9876,请确认。 柜员:身份核实完毕。您新的受理编号为eut1j15a058om8gapa87l937h6。 顾客执行完身份确认之后也走向柜台。 恶人:受理编号为9466ir8fgmmk1gn7raeo7ne71。请向卡号99999的账号转账3万元。 柜员:您还没有进行身份核实。请提供您的银行卡号和密码。
需求3防止会话ID泄露。会话ID泄露的原因:
-
发行cookie时的属性制定有问题
cookie属性
属性 含义 Domain cookie发送对象服务器的域名 Path cookie发送对象URL的路径 Expires cookie的有效期限。未指定则表示至浏览器关闭为止 Secure 仅在SSL加密的情况下发送cookie HttpOnly 制定了此属性的cookie不能被javascript访问 -
Domain属性
cookie在默认情况下只能被发送到与其绑定的服务器。虽然从安全行方面考虑这样是最安全的,但又是也需要向多个服务器发送cookie,这是就要用到domain属性。
如果指定的Domain属性过大,就会导致会话固定攻击。
-
-
会话ID在网络上被监听
-
通过跨站脚本漏洞等应用中的安全隐患被泄露
-
由于PHP或浏览器等平台存在安全隐患而被泄露
-
会话ID保存在URL中的情况下,会通过Referer消息头泄露
参考:
https://blog.csdn.net/h_MXC/article/details/50542038
http://www.cnblogs.com/phpstudy2015-6/p/6776919.html#_label9
https://zhum.in/blog/network/WebSecurity/Web安全之Session管理机制/
https://cloud.tencent.com/developer/article/1192672