JWT(JSON web Token)
JWT(JSON web Token)
JWT 是 JSON Web Token 的缩写,是一种基于 JSON 的开放标准(RFC 7519),用于在网络应用中安全地传输信息。它广泛应用于用户身份验证和授权,尤其在跨域认证场景中非常流行。
JWT 的组成部分
JWT 由三个部分组成,每部分通过点号(.)分隔:
Header(头部):包含元数据,如签名算法"alg":(如 HS256)和令牌类型"typ":(JWT)。 Payload(载荷):存储实际传输的数据,例如用户信息和声明(Claims)。声明分为注册声明(如 iat、exp)、公共声明和私有声明。Signature(签名):通过头部、载荷和密钥生成,用于验证数据完整性,防止篡改。
Header
{
描述JWT的元数据
}
Payload
{
存放实际数据
}
Signature
{
用于哈希运算的密钥
}
图解:

JWT 的特点
无状态性:JWT 是无状态的,所有信息都包含在令牌中,服务端无需存储会话数据,减轻了服务器负担。 跨平台性:基于 JSON 格式,支持多种编程语言和平台。 安全性:通过签名保证数据完整性,可选加密保护敏感信息。 扩展性:支持自定义声明,满足不同业务需求。
使用场景
JWT 常用于用户登录认证。服务端在用户登录成功后生成 JWT,客户端保存该令牌(如存储在 localStorage 或 Cookie 中)。后续请求中,客户端将 JWT 放入 HTTP 请求头的 Authorization 字段,服务端通过验证 JWT 签名来确认用户身份。
不要存储敏感信息:JWT 默认不加密,任何人都可以解码其内容。
设置过期时间:通过 exp 声明限制令牌有效期,避免长期有效的安全风险。
使用 HTTPS:确保令牌在传输过程中不被窃取。
保护密钥:签名的安全性依赖于密钥,密钥泄露会导致安全问题。
JWT 是一种高效、灵活的认证方式,但需要合理设计和使用以确保安全性。
渗透流程
整体渗透测试流程
环境:好靶场平台(网络安全靶场-好靶场平台-安全靶场)
一个标准的JWT渗透测试可以遵循以下步骤:
1、 确定Token位置与作用域:首先,需要定位JWT在请求中的位置(通常在Authorization: Bearer <JWT>头中),并通过移除不同Cookie或Header来确认哪个Token真正控制着当前会话的权限。
JWT一般是eyJ......开头的字符串,之前也提到过JWT由三部分组成,所以这串字符串一般是三段由.隔开

2、解码与结构分析:将获取到的JWT用工具进行解码,仔细检查其Header和Payload部分。
- Header关注:"alg" (算法)、"typ"(类型) 等字段。
- Payload关注:"username"(用户名)、"role"(角色) ,除此之外还有"admin"(权限)、"exp"(过期时间)等敏感信息。

3、 漏洞探测与利用:根据分析结果,进行针对性的漏洞测试。
把这些user用户的信息改成admin,生成一个新的JWT

4、权限提升与持久化:成功利用漏洞后,尝试伪造高权限用户的Token(如管理员),访问受限功能,并检查Token的过期时间,评估风险。
把新的JWT复制到token里面再刷新页面状态

刷新过后就能看到目前用户名身份以及邮箱变为了admin用户的登录状态

核心攻击手法与思路
以下是几种最核心的JWT攻击手法:
alg: none算法绕过:最直接的攻击方式。将Header中的alg字段改为none,并移除签名部分,使服务器不验证签名,从而任意伪造Token。- 工具利用:使用
jwt_tool可以自动化此攻击。 - 手工利用:构造
{"alg":"none"}的Header,保留原Payload,最后以空字符串作为签名。
- 工具利用:使用
- 算法混淆攻击 (RS256 → HS256):当服务器支持多种算法时,攻击者可将
RS256(非对称)改为HS256(对称),并使用服务器的公钥作为HMAC的密钥来签名Token。- 利用方式:获取服务器的RSA公钥(常见于
/.well-known/jwks.json),然后用该公钥作为密钥,用HS256算法重新签名Token。 - 工具利用:
jwt_tool的-X k或-X a参数可以尝试此类攻击。
- 利用方式:获取服务器的RSA公钥(常见于
- 暴力破解弱HMAC密钥:如果JWT使用HS256算法且密钥强度较弱,可以捕获一个合法Token后,使用工具离线暴力破解密钥。
- 工具利用:
jwt_tool的-C参数配合字典进行破解。也可使用hashcat进行高速破解。
- 工具利用:
- Header参数注入:攻击者可在JWT Header中注入特殊参数,诱使服务器从攻击者控制的来源获取验证密钥。
kid(Key ID) 注入:修改kid参数为../../etc/passwd等路径或SQL注入语句,可能导致路径遍历或命令执行。jku(JWK Set URL) 注入:将jku指向一个攻击者控制的URL,该URL返回一个包含攻击者公钥的JWK集,使服务器使用该公钥验证Token。
- Payload篡改:如果应用未校验签名或存在逻辑漏洞,直接修改Payload中的用户ID、角色等字段可能生效。
防御建议
- 严格限制算法,拒绝
none,避免算法混淆。 - 使用强密钥,并定期轮换。
- 严格校验
kid、jku等参数,防止注入。 - 必须验证签名,不能只解码。
- 设置合理的过期时间 (
exp)。
RS256中的“R”代表RSA加密算法。