mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Add Authlib modeling and tests
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
private import python
|
||||
private import experimental.semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
private import experimental.semmle.python.frameworks.JWT
|
||||
|
||||
private module Authlib {
|
||||
/** Gets a reference to `authlib.jose` */
|
||||
private API::Node authlib() { result = API::moduleImport("authlib.jose") }
|
||||
|
||||
/** Gets a reference to `authlib.jose.(jwt|JsonWebToken)` */
|
||||
private API::Node authlibJWT() {
|
||||
result in [authlib().getMember("jwt"), authlib().getMember("JsonWebToken").getReturn()]
|
||||
}
|
||||
|
||||
/** Gets a reference to `jwt.encode` */
|
||||
private API::Node authlibJWTEncode() { result = authlibJWT().getMember("encode") }
|
||||
|
||||
/** Gets a reference to `jwt.decode` */
|
||||
private API::Node authlibJWTDecode() { result = authlibJWT().getMember("decode") }
|
||||
|
||||
// def encode(self, header, payload, key, check=True):
|
||||
private class AuthlibJWTEncodeCall extends DataFlow::CallCfgNode, JWTEncoding::Range {
|
||||
AuthlibJWTEncodeCall() { this = authlibJWTEncode().getACall() }
|
||||
|
||||
override DataFlow::Node getPayload() { result = this.getArg(1) }
|
||||
|
||||
override DataFlow::Node getKey() { result = this.getArg(2) }
|
||||
|
||||
override DataFlow::Node getAlgorithm() {
|
||||
exists(KeyValuePair headerDict |
|
||||
headerDict = this.getArg(0).asExpr().(Dict).getItems().getAnItem() and
|
||||
headerDict.getKey().(Str_).getS().matches("alg") and
|
||||
result.asExpr() = headerDict.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
override string getAlgorithmString() {
|
||||
exists(StrConst str |
|
||||
DataFlow::exprNode(str).(DataFlow::LocalSourceNode).flowsTo(getAlgorithm()) and
|
||||
result = str.getText()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// def decode(self, s, key, claims_cls=None, claims_options=None, claims_params=None):
|
||||
private class AuthlibJWTDecodeCall extends DataFlow::CallCfgNode, JWTDecoding::Range {
|
||||
AuthlibJWTDecodeCall() { this = authlibJWTDecode().getACall() }
|
||||
|
||||
override DataFlow::Node getPayload() { result = this.getArg(0) }
|
||||
|
||||
override DataFlow::Node getKey() { result = this.getArg(1) }
|
||||
|
||||
override DataFlow::Node getAlgorithm() { none() }
|
||||
|
||||
override string getAlgorithmString() { none() }
|
||||
|
||||
override DataFlow::Node getOptions() { none() }
|
||||
|
||||
override predicate verifiesSignature() { any() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
from authlib.jose import jwt # It is already a JsonWebToken object
|
||||
from authlib.jose import JsonWebToken
|
||||
|
||||
# Encoding
|
||||
|
||||
# good - key and algorithm supplied
|
||||
jwt.encode({"alg": "HS256"}, token, "key")
|
||||
JsonWebToken().encode({"alg": "HS256"}, token, "key")
|
||||
|
||||
# bad - empty key
|
||||
jwt.encode({"alg": "HS256"}, token, "")
|
||||
JsonWebToken().encode({"alg": "HS256"}, token, "")
|
||||
|
||||
# Decoding
|
||||
|
||||
# good - "it will raise BadSignatureError when signature doesn’t match"
|
||||
jwt.decode(token, key)
|
||||
JsonWebToken().decode(token, key)
|
||||
Reference in New Issue
Block a user