mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
update tests to contain the new source, delete query with local sources
This commit is contained in:
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* @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 medium
|
||||
* @id java/missing-jwt-signature-check-auth0-local-source
|
||||
* @tags security
|
||||
* external/cwe/cwe-347
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import JwtAuth0 as JwtAuth0
|
||||
|
||||
module JwtDecodeConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(Variable v |
|
||||
source.asExpr() = v.getInitializer() and
|
||||
v.getType().hasName("String")
|
||||
) and
|
||||
not FlowToJwtVerify::flow(source, _)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(JwtAuth0::GetPayload a) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
// Decode Should be one of the middle nodes
|
||||
exists(JwtAuth0::Decode a |
|
||||
nodeFrom.asExpr() = a.getArgument(0) and
|
||||
nodeTo.asExpr() = a
|
||||
)
|
||||
or
|
||||
exists(JwtAuth0::Verify a |
|
||||
nodeFrom.asExpr() = a.getArgument(0) and
|
||||
nodeTo.asExpr() = a
|
||||
)
|
||||
or
|
||||
exists(JwtAuth0::GetPayload a |
|
||||
nodeFrom.asExpr() = a.getQualifier() and
|
||||
nodeTo.asExpr() = a
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module FlowToJwtVerifyConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(Variable v |
|
||||
source.asExpr() = v.getInitializer() and
|
||||
v.getType().hasName("String")
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(JwtAuth0::Verify a).getArgument(0) }
|
||||
}
|
||||
|
||||
module JwtDecode = TaintTracking::Global<JwtDecodeConfig>;
|
||||
|
||||
module FlowToJwtVerify = TaintTracking::Global<FlowToJwtVerifyConfig>;
|
||||
|
||||
import JwtDecode::PathGraph
|
||||
|
||||
from JwtDecode::PathNode source, JwtDecode::PathNode sink
|
||||
where JwtDecode::flowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "This parses a $@, but the signature is not verified.",
|
||||
source.getNode(), "JWT"
|
||||
@@ -1,24 +1,31 @@
|
||||
edges
|
||||
| JwtNoVerifier.java:42:28:42:55 | getParameter(...) : String | JwtNoVerifier.java:43:39:43:47 | JwtToken2 : String | provenance | Src:MaD:44684 |
|
||||
| JwtNoVerifier.java:43:39:43:47 | JwtToken2 : String | JwtNoVerifier.java:72:38:72:55 | token : String | provenance | |
|
||||
| JwtNoVerifier.java:72:38:72:55 | token : String | JwtNoVerifier.java:73:37:73:41 | token : String | provenance | |
|
||||
| JwtNoVerifier.java:73:26:73:42 | decode(...) : DecodedJWT | JwtNoVerifier.java:74:28:74:30 | jwt : DecodedJWT | provenance | |
|
||||
| JwtNoVerifier.java:73:37:73:41 | token : String | JwtNoVerifier.java:73:26:73:42 | decode(...) : DecodedJWT | provenance | Config |
|
||||
| JwtNoVerifier.java:74:16:74:31 | of(...) : Optional [<element>] : DecodedJWT | JwtNoVerifier.java:74:37:74:40 | item : DecodedJWT | provenance | MaD:43977 |
|
||||
| JwtNoVerifier.java:74:28:74:30 | jwt : DecodedJWT | JwtNoVerifier.java:74:16:74:31 | of(...) : Optional [<element>] : DecodedJWT | provenance | MaD:43979 |
|
||||
| JwtNoVerifier.java:74:37:74:40 | item : DecodedJWT | JwtNoVerifier.java:74:45:74:48 | item : DecodedJWT | provenance | |
|
||||
| JwtNoVerifier.java:74:45:74:48 | item : DecodedJWT | JwtNoVerifier.java:74:45:74:69 | getClaim(...) | provenance | Config |
|
||||
| JwtNoVerifier.java:44:28:44:55 | getParameter(...) : String | JwtNoVerifier.java:45:39:45:47 | JwtToken1 : String | provenance | Src:MaD:44685 |
|
||||
| JwtNoVerifier.java:45:39:45:47 | JwtToken1 : String | JwtNoVerifier.java:89:38:89:55 | token : String | provenance | |
|
||||
| JwtNoVerifier.java:58:28:58:62 | (...)... : String | JwtNoVerifier.java:59:32:59:40 | JwtToken3 : String | provenance | |
|
||||
| JwtNoVerifier.java:58:37:58:62 | getCredentials(...) : Object | JwtNoVerifier.java:58:28:58:62 | (...)... : String | provenance | Src:MaD:2352 |
|
||||
| JwtNoVerifier.java:59:32:59:40 | JwtToken3 : String | JwtNoVerifier.java:89:38:89:55 | token : String | provenance | |
|
||||
| JwtNoVerifier.java:89:38:89:55 | token : String | JwtNoVerifier.java:90:37:90:41 | token : String | provenance | |
|
||||
| JwtNoVerifier.java:90:26:90:42 | decode(...) : DecodedJWT | JwtNoVerifier.java:91:28:91:30 | jwt : DecodedJWT | provenance | |
|
||||
| JwtNoVerifier.java:90:37:90:41 | token : String | JwtNoVerifier.java:90:26:90:42 | decode(...) : DecodedJWT | provenance | Config |
|
||||
| JwtNoVerifier.java:91:16:91:31 | of(...) : Optional [<element>] : DecodedJWT | JwtNoVerifier.java:91:37:91:40 | item : DecodedJWT | provenance | MaD:43978 |
|
||||
| JwtNoVerifier.java:91:28:91:30 | jwt : DecodedJWT | JwtNoVerifier.java:91:16:91:31 | of(...) : Optional [<element>] : DecodedJWT | provenance | MaD:43980 |
|
||||
| JwtNoVerifier.java:91:37:91:40 | item : DecodedJWT | JwtNoVerifier.java:91:45:91:48 | item : DecodedJWT | provenance | |
|
||||
| JwtNoVerifier.java:91:45:91:48 | item : DecodedJWT | JwtNoVerifier.java:91:45:91:69 | getClaim(...) | provenance | Config |
|
||||
nodes
|
||||
| JwtNoVerifier.java:42:28:42:55 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| JwtNoVerifier.java:43:39:43:47 | JwtToken2 : String | semmle.label | JwtToken2 : String |
|
||||
| JwtNoVerifier.java:72:38:72:55 | token : String | semmle.label | token : String |
|
||||
| JwtNoVerifier.java:73:26:73:42 | decode(...) : DecodedJWT | semmle.label | decode(...) : DecodedJWT |
|
||||
| JwtNoVerifier.java:73:37:73:41 | token : String | semmle.label | token : String |
|
||||
| JwtNoVerifier.java:74:16:74:31 | of(...) : Optional [<element>] : DecodedJWT | semmle.label | of(...) : Optional [<element>] : DecodedJWT |
|
||||
| JwtNoVerifier.java:74:28:74:30 | jwt : DecodedJWT | semmle.label | jwt : DecodedJWT |
|
||||
| JwtNoVerifier.java:74:37:74:40 | item : DecodedJWT | semmle.label | item : DecodedJWT |
|
||||
| JwtNoVerifier.java:74:45:74:48 | item : DecodedJWT | semmle.label | item : DecodedJWT |
|
||||
| JwtNoVerifier.java:74:45:74:69 | getClaim(...) | semmle.label | getClaim(...) |
|
||||
| JwtNoVerifier.java:44:28:44:55 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| JwtNoVerifier.java:45:39:45:47 | JwtToken1 : String | semmle.label | JwtToken1 : String |
|
||||
| JwtNoVerifier.java:58:28:58:62 | (...)... : String | semmle.label | (...)... : String |
|
||||
| JwtNoVerifier.java:58:37:58:62 | getCredentials(...) : Object | semmle.label | getCredentials(...) : Object |
|
||||
| JwtNoVerifier.java:59:32:59:40 | JwtToken3 : String | semmle.label | JwtToken3 : String |
|
||||
| JwtNoVerifier.java:89:38:89:55 | token : String | semmle.label | token : String |
|
||||
| JwtNoVerifier.java:90:26:90:42 | decode(...) : DecodedJWT | semmle.label | decode(...) : DecodedJWT |
|
||||
| JwtNoVerifier.java:90:37:90:41 | token : String | semmle.label | token : String |
|
||||
| JwtNoVerifier.java:91:16:91:31 | of(...) : Optional [<element>] : DecodedJWT | semmle.label | of(...) : Optional [<element>] : DecodedJWT |
|
||||
| JwtNoVerifier.java:91:28:91:30 | jwt : DecodedJWT | semmle.label | jwt : DecodedJWT |
|
||||
| JwtNoVerifier.java:91:37:91:40 | item : DecodedJWT | semmle.label | item : DecodedJWT |
|
||||
| JwtNoVerifier.java:91:45:91:48 | item : DecodedJWT | semmle.label | item : DecodedJWT |
|
||||
| JwtNoVerifier.java:91:45:91:69 | getClaim(...) | semmle.label | getClaim(...) |
|
||||
subpaths
|
||||
#select
|
||||
| JwtNoVerifier.java:74:45:74:69 | getClaim(...) | JwtNoVerifier.java:42:28:42:55 | getParameter(...) : String | JwtNoVerifier.java:74:45:74:69 | getClaim(...) | This parses a $@, but the signature is not verified. | JwtNoVerifier.java:42:28:42:55 | getParameter(...) | JWT |
|
||||
| JwtNoVerifier.java:91:45:91:69 | getClaim(...) | JwtNoVerifier.java:44:28:44:55 | getParameter(...) : String | JwtNoVerifier.java:91:45:91:69 | getClaim(...) | This parses a $@, but the signature is not verified. | JwtNoVerifier.java:44:28:44:55 | getParameter(...) | JWT |
|
||||
| JwtNoVerifier.java:91:45:91:69 | getClaim(...) | JwtNoVerifier.java:58:37:58:62 | getCredentials(...) : Object | JwtNoVerifier.java:91:45:91:69 | getClaim(...) | This parses a $@, but the signature is not verified. | JwtNoVerifier.java:58:37:58:62 | getCredentials(...) | JWT |
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
edges
|
||||
| JwtNoVerifier.java:42:28:42:55 | getParameter(...) : String | JwtNoVerifier.java:43:39:43:47 | JwtToken2 : String | provenance | Src:MaD:44684 |
|
||||
| JwtNoVerifier.java:43:39:43:47 | JwtToken2 : String | JwtNoVerifier.java:72:38:72:55 | token : String | provenance | |
|
||||
| JwtNoVerifier.java:72:38:72:55 | token : String | JwtNoVerifier.java:73:37:73:41 | token : String | provenance | |
|
||||
| JwtNoVerifier.java:73:26:73:42 | decode(...) : DecodedJWT | JwtNoVerifier.java:74:28:74:30 | jwt : DecodedJWT | provenance | |
|
||||
| JwtNoVerifier.java:73:37:73:41 | token : String | JwtNoVerifier.java:73:26:73:42 | decode(...) : DecodedJWT | provenance | Config |
|
||||
| JwtNoVerifier.java:74:16:74:31 | of(...) : Optional [<element>] : DecodedJWT | JwtNoVerifier.java:74:37:74:40 | item : DecodedJWT | provenance | MaD:43977 |
|
||||
| JwtNoVerifier.java:74:28:74:30 | jwt : DecodedJWT | JwtNoVerifier.java:74:16:74:31 | of(...) : Optional [<element>] : DecodedJWT | provenance | MaD:43979 |
|
||||
| JwtNoVerifier.java:74:37:74:40 | item : DecodedJWT | JwtNoVerifier.java:74:45:74:48 | item : DecodedJWT | provenance | |
|
||||
| JwtNoVerifier.java:74:45:74:48 | item : DecodedJWT | JwtNoVerifier.java:74:45:74:69 | getClaim(...) | provenance | Config |
|
||||
nodes
|
||||
| JwtNoVerifier.java:42:28:42:55 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| JwtNoVerifier.java:43:39:43:47 | JwtToken2 : String | semmle.label | JwtToken2 : String |
|
||||
| JwtNoVerifier.java:72:38:72:55 | token : String | semmle.label | token : String |
|
||||
| JwtNoVerifier.java:73:26:73:42 | decode(...) : DecodedJWT | semmle.label | decode(...) : DecodedJWT |
|
||||
| JwtNoVerifier.java:73:37:73:41 | token : String | semmle.label | token : String |
|
||||
| JwtNoVerifier.java:74:16:74:31 | of(...) : Optional [<element>] : DecodedJWT | semmle.label | of(...) : Optional [<element>] : DecodedJWT |
|
||||
| JwtNoVerifier.java:74:28:74:30 | jwt : DecodedJWT | semmle.label | jwt : DecodedJWT |
|
||||
| JwtNoVerifier.java:74:37:74:40 | item : DecodedJWT | semmle.label | item : DecodedJWT |
|
||||
| JwtNoVerifier.java:74:45:74:48 | item : DecodedJWT | semmle.label | item : DecodedJWT |
|
||||
| JwtNoVerifier.java:74:45:74:69 | getClaim(...) | semmle.label | getClaim(...) |
|
||||
subpaths
|
||||
#select
|
||||
| JwtNoVerifier.java:74:45:74:69 | getClaim(...) | JwtNoVerifier.java:42:28:42:55 | getParameter(...) : String | JwtNoVerifier.java:74:45:74:69 | getClaim(...) | This parses a $@, but the signature is not verified. | JwtNoVerifier.java:42:28:42:55 | getParameter(...) | JWT |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security/CWE/CWE-347/Auth0NoVerifierLocalSource.ql
|
||||
@@ -11,6 +11,8 @@ import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.BearerToken;
|
||||
|
||||
public class JwtNoVerifier extends HttpServlet {
|
||||
|
||||
@@ -39,8 +41,22 @@ public class JwtNoVerifier extends HttpServlet {
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
// NOT OK: only decode, no verification
|
||||
String JwtToken1 = request.getParameter("JWT2");
|
||||
String userName = decodeToken(JwtToken1);
|
||||
if (Objects.equals(userName, "Admin")) {
|
||||
out.println("<html><body>");
|
||||
out.println("<h1>" + "heyyy Admin" + "</h1>");
|
||||
out.println("</body></html>");
|
||||
}
|
||||
|
||||
AuthenticationToken authToken = new BearerToken("admin", "admin");
|
||||
// OK: no clue of the use of unsafe decoded JWT return value
|
||||
String JwtToken2 = request.getParameter("JWT2");
|
||||
String userName = decodeToken(JwtToken2);
|
||||
JWT.decode(JwtToken2);
|
||||
|
||||
// NOT OK: only decode, no verification
|
||||
String JwtToken3 = (String) authToken.getCredentials();
|
||||
userName = decodeToken(JwtToken3);
|
||||
if (Objects.equals(userName, "Admin")) {
|
||||
out.println("<html><body>");
|
||||
out.println("<h1>" + "heyyy Admin" + "</h1>");
|
||||
@@ -48,9 +64,10 @@ public class JwtNoVerifier extends HttpServlet {
|
||||
}
|
||||
|
||||
// OK: no clue of the use of unsafe decoded JWT return value
|
||||
JwtToken2 = request.getParameter("JWT2");
|
||||
JWT.decode(JwtToken2);
|
||||
String JwtToken4 = (String) authToken.getCredentials();
|
||||
JWT.decode(JwtToken4);
|
||||
|
||||
|
||||
|
||||
out.println("<html><body>");
|
||||
out.println("<h1>" + "heyyy Nobody" + "</h1>");
|
||||
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/auth0-java-jwt-4.4.0:${testdir}/../../../../stubs/javax-servlet-2.5
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/auth0-java-jwt-4.4.0:${testdir}/../../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/org-apache-shiro-authc-2.0.1
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// Generated automatically from org.apache.shiro.authc.AuthenticationToken for testing purposes
|
||||
|
||||
package org.apache.shiro.authc;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface AuthenticationToken extends Serializable
|
||||
{
|
||||
Object getCredentials();
|
||||
Object getPrincipal();
|
||||
}
|
||||
16
java/ql/test/experimental/stubs/org-apache-shiro-authc-2.0.1/org/apache/shiro/authc/BearerToken.java
generated
Normal file
16
java/ql/test/experimental/stubs/org-apache-shiro-authc-2.0.1/org/apache/shiro/authc/BearerToken.java
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
// Generated automatically from org.apache.shiro.authc.BearerToken for testing purposes
|
||||
|
||||
package org.apache.shiro.authc;
|
||||
|
||||
import org.apache.shiro.authc.HostAuthenticationToken;
|
||||
|
||||
public class BearerToken implements HostAuthenticationToken
|
||||
{
|
||||
protected BearerToken() {}
|
||||
public BearerToken(String p0){}
|
||||
public BearerToken(String p0, String p1){}
|
||||
public Object getCredentials(){ return null; }
|
||||
public Object getPrincipal(){ return null; }
|
||||
public String getHost(){ return null; }
|
||||
public String getToken(){ return null; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.apache.shiro.authc.HostAuthenticationToken for testing purposes
|
||||
|
||||
package org.apache.shiro.authc;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
|
||||
public interface HostAuthenticationToken extends AuthenticationToken
|
||||
{
|
||||
String getHost();
|
||||
}
|
||||
Reference in New Issue
Block a user