CodeQL 文档

缺少 JWT 签名检查

ID: java/missing-jwt-signature-check
Kind: path-problem
Security severity: 7.8
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-347
Query suites:
   - java-code-scanning.qls
   - java-security-extended.qls
   - java-security-and-quality.qls

单击以在 CodeQL 存储库中查看查询

JSON Web 令牌 (JWT) 由三部分组成:标头、有效负载和签名。io.jsonwebtoken.jjwt 库是用于处理 JWT 的众多库之一。它提供了用于解析令牌的不同方法,如 parseparseClaimsJwsparsePlaintextJws。后两个方法正确验证了 JWT 已正确签名。这是通过计算标头和有效负载的组合签名,并将本地计算的签名与 JWT 的签名部分进行比较来完成的。

因此,有必要为 JwtParser 提供用于签名验证的密钥。不幸的是,parse 方法接受签名为空的 JWT,即使已为解析器设置了签名密钥。这意味着攻击者可以创建任意 JWT,如果使用此方法,这些 JWT 将被接受。

建议

始终使用 parseClaimsJwsparsePlaintextJws 方法或覆盖 JwtHandlerAdapteronPlaintextJwsonClaimsJws 来验证签名。

示例

以下示例展示了为解析器设置签名密钥的四种情况。在第一个“BAD”情况下,使用了 parse 方法,该方法不会验证签名。第二个“BAD”情况使用 JwtHandlerAdapter,其中 onPlaintextJwt 方法被覆盖,因此它不会验证签名。第三个和第四个“GOOD”情况使用 parseClaimsJws 方法或覆盖 onPlaintextJws 方法。

public void badJwt(String token) {
    Jwts.parserBuilder()
                .setSigningKey("someBase64EncodedKey").build()
                .parse(token); // BAD: Does not verify the signature
}

public void badJwtHandler(String token) {
    Jwts.parserBuilder()
                .setSigningKey("someBase64EncodedKey").build()
                .parse(plaintextJwt, new JwtHandlerAdapter<Jwt<Header, String>>() {
                    @Override
                    public Jwt<Header, String> onPlaintextJwt(Jwt<Header, String> jwt) {
                        return jwt;
                    }
                }); // BAD: The handler is called on an unverified JWT
}

public void goodJwt(String token) {
    Jwts.parserBuilder()
                .setSigningKey("someBase64EncodedKey").build()
                .parseClaimsJws(token) // GOOD: Verify the signature
                .getBody();
}

public void goodJwtHandler(String token) {
    Jwts.parserBuilder()
                .setSigningKey("someBase64EncodedKey").build()
                .parse(plaintextJwt, new JwtHandlerAdapter<Jws<String>>() {
                    @Override
                    public Jws<String> onPlaintextJws(Jws<String> jws) {
                        return jws;
                    }
                }); // GOOD: The handler is called on a verified JWS
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私