mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Model python_jwt.process_jwt
This commit is contained in:
@@ -11,5 +11,6 @@ private import experimental.semmle.python.frameworks.NoSQL
|
||||
private import experimental.semmle.python.frameworks.Log
|
||||
private import experimental.semmle.python.frameworks.JWT
|
||||
private import experimental.semmle.python.libraries.PyJWT
|
||||
private import experimental.semmle.python.libraries.Python_JWT
|
||||
private import experimental.semmle.python.libraries.Authlib
|
||||
private import experimental.semmle.python.libraries.PythonJose
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
private import python
|
||||
private import experimental.semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
private module Python_JWT {
|
||||
/**
|
||||
* Gets a call to `python_jwt.process_jwt`.
|
||||
*
|
||||
* Given the following example:
|
||||
*
|
||||
* ```py
|
||||
* python_jwt.process_jwt(token)
|
||||
* python_jwt.verify_jwt(token, "key", "HS256")
|
||||
* ```
|
||||
*
|
||||
* * `this` would be `jwt.process_jwt(token)`.
|
||||
* * `getPayload()`'s result would be `token`.
|
||||
* * `getKey()`'s result would be `"key"`.
|
||||
* * `getAlgorithm()`'s result would be `"HS256"`.
|
||||
* * `getAlgorithmstring()`'s result would be `HS256`.
|
||||
* * `getOptions()`'s result would be `none()`.
|
||||
* * `verifiesSignature()` predicate would succeed.
|
||||
*/
|
||||
private class Python_JWTProcessCall extends DataFlow::CallCfgNode, JWTDecoding::Range {
|
||||
DataFlow::CallCfgNode verifyCall;
|
||||
boolean verifiesSignature;
|
||||
|
||||
Python_JWTProcessCall() {
|
||||
this = API::moduleImport("python_jwt").getMember("process_jwt").getACall() and
|
||||
(
|
||||
verifyCall = API::moduleImport("python_jwt").getMember("verify_jwt").getACall() and
|
||||
this.getArg(0).getALocalSource().flowsTo(verifyCall.getArg(0)) and
|
||||
verifiesSignature = true
|
||||
or
|
||||
verifiesSignature = false
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getPayload() { result = this.getArg(0) }
|
||||
|
||||
override DataFlow::Node getKey() { result = verifyCall.getArg(1) }
|
||||
|
||||
override DataFlow::Node getAlgorithm() { result = verifyCall.getArg(2) }
|
||||
|
||||
override string getAlgorithmString() {
|
||||
exists(StrConst str |
|
||||
DataFlow::exprNode(str).(DataFlow::LocalSourceNode).flowsTo(this.getAlgorithm()) and
|
||||
result = str.getText()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getOptions() { none() }
|
||||
|
||||
override predicate verifiesSignature() { exists( | verifiesSignature = true) }
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
| pyjwt.py:22:12:22:16 | ControlFlowNode for token | is not verified with a cryptographic secret or public key. |
|
||||
| pyjwt.py:23:12:23:16 | ControlFlowNode for token | is not verified with a cryptographic secret or public key. |
|
||||
| python_jose.py:19:12:19:16 | ControlFlowNode for token | is not verified with a cryptographic secret or public key. |
|
||||
| python_jwt.py:14:24:14:29 | ControlFlowNode for token3 | is not verified with a cryptographic secret or public key. |
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import python_jwt
|
||||
|
||||
# GOOD
|
||||
|
||||
token1 = "1"
|
||||
python_jwt.process_jwt(token1)
|
||||
python_jwt.verify_jwt(token1, "key", "HS256")
|
||||
|
||||
# BAD
|
||||
|
||||
# no call to verify_jwt
|
||||
|
||||
token3 = "123"
|
||||
python_jwt.process_jwt(token3)
|
||||
Reference in New Issue
Block a user