JWT安全性漫谈

JWT安全性漫谈

JSON Web Token (JWT, sometimes pronounced /dʒɒt/[1]) is a JSON-based open standard (RFC 7519) for creating access tokens that assert some number of claims. For example, a server could generate a token that has the claim “logged in as admin” and provide that to a client. The client could then use that token to prove that it is logged in as admin. The tokens are signed by the server’s key, so the client and server are both able to verify that the token is legitimate. The tokens are designed to be compact, URL-safe and usable especially in web browser single sign-on (SSO) context. JWT claims can be typically used to pass identity of authenticated users between an identity provider and a service provider, or any other type of claims as required by business processes. The tokens can also be authenticated and encrypted.

介绍

JWT的接口主要有3部分构成。Header,Payload,Signature。
JSON Web Token (JWT)现在越来越方便,因为其中有设计的数字签名,可以防止数据包被修改。而且,服务端不需要保存用户的状态(传统解决方案是利用session来解决,session是需要保存到服务端的)。由于在头部,所以token被获取的难度大。

  • Header: The header contains the metadata for the token and at a minimal contains the type of the signature and/or encryption algorithm
  • Claims: The claims contains any information that you want signed
  • JSON Web Signature (JWS): The headers and claims digitally signed using the algorithm in the specified in the header
1
2
3
4
5
6
7
8
9
10
11
12
//header
{
"alg": "HS256", //denotes the algorithm (shorthand alg) used for the signature is HMAC SHA-256
"typ": "JWT" //denotes the type (shorthand typ) of token this is
}

//claims
{
"sub": "tom@stormpath.com",
"name": "Tom Abbott",
"role": "user"
}

那么安全性也可以由这3部分展开

  • Support for “ None” algorithm disabled
  • No Injection in the “kid” element
  • Embedded “jwk” elements are not trusted
  • White list of algorithms enforced
  • Replay protection via “jti” element
Pyalod
  • Check for sensitive information stored in the payload
  • Check for token’ s expiry enforced via “exp” or “iat” elements
Signature
  • Check if the signature is enforced
  • Try to bruteforce the secret key
  • Ensure that keys and secrets are stored outside of source
  • Check that keys and secrets are different between environments
  • Check for time constant verificationf or HMAC

可能存在的风险点

  • 永远记得要验证签名算法,因为发现一些JWT实现的框架发现了漏洞,没有去验证签名算法,如果头部的alg设置为none,那么可能导致数字签名失效,导致可以构造任意token。
  • secret key一定要为随机够长的。否则存在被暴力枚举的风险。因为claim部分是没有加密的,只是base64编码,这样子通过枚举secret key,生成结果和原结果匹配。类似md5的碰撞。github有开源的工具jwt-cracker 但是mac下面有bug,所以最好在Linux下面跑。
  • 由于claim部分是没有加密只是编码,所以,敏感信息(密码等),不要存储在claim。
  • 权限控制,权限控制JWT是没有做的,如果系统设计有权限的区分,那么,需要独自读取claim的内容进行权限判断。比如说username,那么服务端读取到这个用户,那么判断用户的权限,然后再访问接口。

工具

参考链接