会话与令牌
“必须始终假设前端已泄露,并且攻击者控制着浏览器和网络。”—— 任何仅在客户端隐藏或验证的内容都不可靠(如经过验证的用户显示某菜单)。
服务器端是“最后一道防线”,最重要的安全工作必须在服务器端完成。鉴于客户端可能被攻破,服务器必须执行所有验证。
HTTP的无状态性如何影响Web应用程序的安全性?
HTTP本质上是无状态的,每次请求都是独立的,没有上下文可以利用。为了在HTTP请求之间维护上下文(例如用户登录状态),通常使用会话ID或令牌作为标记。会话ID通常存储在cookie中,也可以使用session storage或local storage。如果会话ID或令牌被盗,攻击者可以利用它们来冒充用户。
会话(Sessions)
一方面需要服务器端维护的会话对象,另一方面需要客户端存储的会话ID。
当用户登录时,服务器会生成一个会话ID并将其发送给客户端。随后的请求会携带此会话ID,服务器通过查找其内部存储的会话对象来识别用户。
优点是成熟稳定,且会话ID本身不包含有意义的数据。缺点是服务器需要存储会话信息,这在水平扩展时可能需要额外的复杂性(如[[粘性会话]]或[[共享会话存储]]),并且需要额外的机制来防范CSRF攻击。
适用于: 单体服务器环境中,开发团队对后端有完全控制权,并可以轻松实现服务器端会话管理时,对于大多数不需要处理像Reddit那样巨大流量的应用,会话cookie通常足够。
与会话ID安全相关的Cookie设置有以下两个:
- HttpOnly Cookie: 将Cookie设置为HttpOnly意味着客户端JavaScript无法访问该Cookie,从而防止恶意脚本(例如通过XSS注入)窃取Cookie信息(特别是会话ID)。
- Secure Cookie: 将Cookie设置为Secure意味着该Cookie将只通过安全的HTTPS连接发送。
令牌(Tokens)
通常指的是自包含令牌,如[[JSON Web Tokens (JWT)]]。
用户登录后,服务器会生成一个包含用户信息(如用户名、角色、过期时间)并经过加密签名的令牌。客户端存储此令牌,并在每次请求时通过HTTP授权头部发送。服务器通过验证令牌的签名来验证其真实性和完整性,而无需在服务器端存储任何会话信息。
优点是无状态,易于水平扩展,并且可以与多个域或后端通信。缺点是令牌一旦被发出就难以立即失效(通常通过设置短的有效期或黑名单来解决,但黑名单会破坏无状态性),且需要确保签名密钥的安全性。
适用于:
- 分布式企业环境:当有多个后端或服务,且这些服务之间需要共享认证信息,但团队之间可能存在安全或访问限制时。
- 多域/多源通信:当需要与不同域或来源的API进行通信时,JWT由于可以通过HTTP授权头部发送,不受同源策略的限制。
- 第三方API授权:为第三方客户端提供短期、自包含的访问令牌,以便其调用特定API。
- 短期授权/一次性授权:例如,用于下载文件的短期授权链接。
- OAuth 2.0和OpenID Connect等协议:这些认证和授权协议广泛使用令牌。
尽管有签名验证策略,JSON Web 令牌 (JWT) 也存在一些常见的安全漏洞:
- 敏感数据泄露: JWT 的有效负载是 Base64 编码的,而不是加密的。任何能够解码 Base64 的人都可以看到有效负载的内容。因此,不应在 JWT 有效负载中存储任何敏感或机密数据。
- “none”算法漏洞: JWT 规范允许使用“none”算法,表示没有签名,这导致了早期 JWT 库e的漏洞。攻击者将头部中的算法设置为“none”后,可以制作包含任意有效负载的令牌。
- 算法混淆(RS256 到 HS256): 【TODO】如果系统使用非对称加密(RS256)进行签名(使用私钥签名,使用公钥验证),攻击者可能会尝试将头部中的算法更改为对称加密(HS256)。由于公钥通常是公开的,攻击者可以使用该公钥作为 HS256 算法的密钥来签名他们的恶意令牌。如果服务器的库未能正确处理这种混淆,它可能会使用公钥作为 HS256 密钥来验证令牌,并接受攻击者的伪造令牌。
- 弱密钥/密钥暴力破解: 【TODO】HS256 等算法需要一个秘密密钥来签名和验证令牌。如果秘密密钥较弱或容易被猜到,攻击者可以通过暴力破解来猜测密钥。一旦猜到密钥,攻击者就可以签名任何有效负载,并冒充任何用户或欺骗后端接受恶意令牌。建议使用足够长度(例如,HS256 至少 32 字节或 256 位)的强随机密钥。
- 未经验证的过期时间: JWT 可以包含过期时间戳,但某些库默认不检查此过期时间戳。确保使用的 JWT 库或的代码明确强制执行过期检查。
HTTPS在Web安全中的作用是什么?
令牌和Cookie安全都与HTTPS相关。HTTPS(超文本传输安全协议)通过加密客户端和服务器之间的通信来防止中间人攻击。它还支持许多现代Web功能,如Service Workers、推送通知、地理定位、摄像头和麦克风访问等。
像“Let's Encrypt”这样的项目使得免费获取和设置SSL/TLS证书变得容易,推动了HTTPS的普及。
令牌、会话与“是否同源”的关系
如果使用Cookies进行认证,通常是在同源(same origin)环境下工作,并且需要启用跨站请求伪造(CSRF)保护。
如果设置了CORS,通常意味着前端和后端位于不同源,这时更倾向于使用令牌(tokens)进行认证。