mirror of
https://github.com/github/codeql.git
synced 2025-12-22 03:36:30 +01:00
Merge pull request #5911 from atorralba/atorralba/promote-missing-jwt-signature-check
Java: Promote Missing JWT signature check query from experimental
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p> A JSON Web Token (JWT) consists of three parts: header, payload, and signature.
|
||||
The <code>io.jsonwebtoken.jjwt</code> library is one of many libraries used for working with JWTs.
|
||||
It offers different methods for parsing tokens like <code>parse</code>, <code>parseClaimsJws</code>, and <code>parsePlaintextJws</code>.
|
||||
The last two correctly verify that the JWT is properly signed.
|
||||
This is done by computing the signature of the combination of header and payload and
|
||||
comparing the locally computed signature with the signature part of the JWT.
|
||||
</p>
|
||||
<p>
|
||||
Therefore it is necessary to provide the <code>JwtParser</code> with a key that is used for signature validation.
|
||||
Unfortunately the <code>parse</code> method <b>accepts</b> a JWT whose signature is empty although a signing key has been set for the parser.
|
||||
This means that an attacker can create arbitrary JWTs that will be accepted if this method is used.
|
||||
</p>
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>Always verify the signature by using either the <code>parseClaimsJws</code> and <code>parsePlaintextJws</code> methods or
|
||||
by overriding the <code>onPlaintextJws</code> or <code>onClaimsJws</code> of <code>JwtHandlerAdapter</code>.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>The following example shows four cases where a signing key is set for a parser.
|
||||
In the first 'BAD' case the <code>parse</code> method is used, which will not validate the signature.
|
||||
The second 'BAD' case uses a <code>JwtHandlerAdapter</code> where the <code>onPlaintextJwt</code> method is overriden, so it will not validate the signature.
|
||||
The third and fourth 'GOOD' cases use <code>parseClaimsJws</code> method or override the <code>onPlaintextJws</code> method.
|
||||
</p>
|
||||
|
||||
<sample src="MissingJWTSignatureCheck.java" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
<li>zofrex: <a href="https://www.zofrex.com/blog/2020/10/20/alg-none-jwt-nhs-contact-tracing-app/">How I Found An alg=none JWT Vulnerability in the NHS Contact Tracing App</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
20
java/ql/src/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql
Normal file
20
java/ql/src/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @name Missing JWT signature check
|
||||
* @description Failing to check the Json Web Token (JWT) signature may allow an attacker to forge their own tokens.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 7.8
|
||||
* @precision high
|
||||
* @id java/missing-jwt-signature-check
|
||||
* @tags security
|
||||
* external/cwe/cwe-347
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.MissingJWTSignatureCheckQuery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, MissingJwtSignatureCheckConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "A signing key is set $@, but the signature is not verified.",
|
||||
source.getNode(), "here"
|
||||
Reference in New Issue
Block a user