文章目录
总结Cookie安全知识
众所周知,Web的核心协议HTTP是无状态的(在HTTP刚发布时,甚至可能每次请求都要求输入用户信息,极不方便),直到1994年NetScape开发的Cookie发布后,才有了标准化的、广泛使用的技术来标记用户的”会话状态“。
一、Cookie技术
Ⅰ.Cookie?
- Cookie是一段小小的文本数据(通常单个Cookie的最大长度为4KB),在用户完成”身份认证或会话状态更新“后,它会被服务端放在HTTP响应包的
Set-Cookie
中,并发送给客户端进行保存(存储方式可能视浏览器而不同)
Ⅱ.Cookie存了什么?
-
从功能上来讲:
-
Cookie可用于跟踪用户的会话
- SessionID
用户的会话状态信息本体(Session)会被存放在服务端,服务端可用根据HTTP请求中Cookie所存储的SessionID来匹配该用户的会话状态。
(与仅仅存储SessionID相比,直接在Cookie中存储登录ID和密码是更危险的,这点后面会讲到)
-
Cookie可用于记录用户的偏好(用户下次访问网站时会自动应用这些偏好)
- 用户的偏好语言
- 用户的偏好主题
- ……
-
其他方便的功能(购物车、跟踪广告等)
-
-
从安全角度:
- Cookie往往会存有服务端在发送Cookie时设定的安全标记
Secure
expires
Domain
- ……
- Cookie往往会存有服务端在发送Cookie时设定的安全标记
二、Cookie的安全问题
1. 窃取
-
Cookie窃取:攻击者劫持到用户的Cookie本身
-
想要维持登陆状态的话,大多数情况下攻击者只需拿到Cookie中的SessionID
-
利用XSS注入恶意脚本来收集Cookie
-
通过网络嗅探和拦截来窃取Cookie
嗅探是被动的网络监听,拦截是主动的拦截修改(举个例子:前者对应WireShark,后者对应BurpSuite)
-
2. 欺骗
-
Cookie欺骗:篡改或伪造Cookie
-
篡改:
①利用XSS注入恶意脚本来修改Cookie
②利用CSRF伪造包含恶意Cookie的请求
-
伪造:
①查看合法Cookie的结构,并尝试模仿伪造
②假如攻击者知道某Web站点的Cookie生成算法,那么他可能会尝试去构造出有效的Cookie
-
3.注入
如果不进行恰当的处理(如过滤、转义),那么Cookie很可能成为注入攻击的突破点
- CRLF攻击
- 假如用户能够控制服务端HTTP响应的
Set-Cookie
字段的值,且服务端未对即将写入Cookie的值进行恰当的过滤和转义,那么攻击者很有可能通过注入CRLF(回车换行)
来截断并控制HTTP响应包的内容
- 假如用户能够控制服务端HTTP响应的
- SQL注入
- 同样地,如果服务端没有对Cookie的值进行恰当的过滤,那么攻击者很可能将此作为注入点
三、安全使用Cookie
Ⅰ.服务器发送Cookie
-
限制敏感信息写入Cookie:
如果要通过Cookie来维持用户的登录状态,请务必不要存储 “登录ID、密码” 等敏感信息,而是应该在服务端存储用户的会话状态Session,并用对应的SessionID来替代上述的敏感信息。
-
SessionID可被设置过期时间,攻击者将更难维持持久的登录状态
-
SessionID实际不包含有意义的敏感信息,在诸如“需要原密码的密码重置”等场景,攻击者便难以简单地施展攻击
-
哪怕原密码被“加密”,如果是用了不安全的散列函数,或者仅仅是进行了某种编码,也很(这里加密打引号是因为散列函数并不能称为一种“加密”,它是不可逆的,更准确地应该称其为一种“保密手段”)
-
-
在向
Set-Cookie
中写入内容前,要进行过滤-
过滤特殊字符:
防止针对Cookie的CRLF攻击【如果当Cookie的某些内容是可由用户控制的,那么千万要在写入
Set-Cookie
时对内容进行过滤,尤其是换行符、截断符等】
-
-
做Cookie的访问控制
-
在HTTP响应的
Set-Cookie
中添加HttpOnly
属性,设置Cookie的访问对象,防止恶意脚本等去访问Cookie:Set-Cookie: name=value; HttpOnly
-
在HTTP响应的
Set-Cookie
中添加Domain
属性,设置Cookie的可用域:Set-Cookie: name=value; Domain=example.com
-
在HTTP响应的
Set-Cookie
中添加Path
属性,设置Cookie的可用路径:Set-Cookie: name=value; Domain=example.com; Path=/
-
-
限制Cookie的传输方式
-
在HTTP响应的
Set-Cookie
字段中添加Secure
属性,以要求Cookie仅在HTTPS下才能传输:Set-Cookie: name=value; Secure
使用HTTPS可用大大提高Cookie在传输过程中的安全性,包括完整性、保密性等。
-
-
限制Cookie的存储
-
在HTTP响应的
Set-Cookie
中添加expires
和max-age
属性,设置过期时间:-
用expires指定绝对时间
Set-Cookie: name=value; expires=Wed, 21 Oct 2021 07:28:00 GMT;
-
用max-age指定存活时间(s)
Set-Cookie: name=value; max-age=3600;
-
-
Ⅱ.服务器处理Cookie
-
对收到的Cookie进行安全检查
- 检查Cookie的安全标记
HttpOnly
Secure
- 过期时间
expires
/max-age
- 可用域
Domain
- 可用路径
Path
- 过滤Cookie中的字符,防范隐藏在Cookie中的SQL注入Payload等
- 检查Cookie的安全标记
-
强化Cookie的完整性校验和对用户的身份鉴别
-
完整性校验:
-
使用数字签名+散列(哈希)函数
(请不要使用MD5、SHA-1等已不再安全的散列函数,如今更安全的选项是SHA-256和SHA-3)
具体如下:
①服务端在发送Cookie时,对Cookie进行哈希得到一个哈希值;并使用私钥对该哈希值进行数字签名,最后将Cookie和签名值一并发送
②客户端收到后立马对Cookie进行哈希,得到一个哈希值;并使用服务端提供的公钥对签名值进行特殊运算(即用私钥签名的逆运算),如果一切正常也将得到一个哈希值,将两个哈希值进行对比,便可得知Cookie是否被篡改
-
-
强化对用户的身份鉴别
- 使用多因子验证(既然Cookie是服务于用户偏好记录或身份验证,那么强化用户访问服务时的身份验证总是没错的)
-
对于无状态的HTTP,Cookie是一种方便的机制,但作为大多数Web情景下的”身份个性化标识“,它的安全问题应该得到足够的重视。