11private import python
2- private import experimental.semmle.python.Concepts
32private import semmle.python.ApiGraphs
43
54predicate isEmptyOrNone ( DataFlow:: Node arg ) { isEmpty ( arg ) or isNone ( arg ) }
@@ -19,72 +18,3 @@ predicate isFalse(DataFlow::Node arg) {
1918 exists ( | DataFlow:: exprNode ( any ( False falseExpr ) ) .( DataFlow:: LocalSourceNode ) .flowsTo ( arg ) )
2019}
2120
22- private module JWT {
23- /** Gets a reference to `jwt` */
24- private API:: Node pyjwt ( ) { result = API:: moduleImport ( "jwt" ) }
25-
26- /** Gets a reference to `jwt.encode` */
27- private API:: Node pyjwt_encode ( ) { result = pyjwt ( ) .getMember ( "encode" ) }
28-
29- /** Gets a reference to `jwt.decode` */
30- private API:: Node pyjwt_decode ( ) { result = pyjwt ( ) .getMember ( "decode" ) }
31-
32- private class PyJWTEncodeCall extends DataFlow:: CallCfgNode , JWTEncoding:: Range {
33- PyJWTEncodeCall ( ) { this = pyjwt_encode ( ) .getACall ( ) }
34-
35- override DataFlow:: Node getPayload ( ) {
36- result in [ this .getArg ( 0 ) , this .getArgByName ( "payload" ) ]
37- }
38-
39- override DataFlow:: Node getKey ( ) { result in [ this .getArg ( 1 ) , this .getArgByName ( "key" ) ] }
40-
41- override DataFlow:: Node getAlgorithm ( ) {
42- result in [ this .getArg ( 2 ) , this .getArgByName ( "algorithm" ) ]
43- }
44-
45- override string getAlgorithmString ( ) {
46- exists ( StrConst str |
47- DataFlow:: exprNode ( str ) .( DataFlow:: LocalSourceNode ) .flowsTo ( getAlgorithm ( ) ) and
48- result = str .getText ( )
49- )
50- }
51- }
52-
53- private class PyJWTDecodeCall extends DataFlow:: CallCfgNode , JWTDecoding:: Range {
54- PyJWTDecodeCall ( ) { this = pyjwt_decode ( ) .getACall ( ) }
55-
56- override DataFlow:: Node getPayload ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "jwt" ) ] }
57-
58- override DataFlow:: Node getKey ( ) { result in [ this .getArg ( 1 ) , this .getArgByName ( "key" ) ] }
59-
60- override DataFlow:: Node getAlgorithm ( ) {
61- result in [ this .getArg ( 2 ) , this .getArgByName ( "algorithms" ) ]
62- }
63-
64- override string getAlgorithmString ( ) {
65- exists ( StrConst str |
66- DataFlow:: exprNode ( str ) .( DataFlow:: LocalSourceNode ) .flowsTo ( getAlgorithm ( ) ) and
67- result = str .getText ( )
68- )
69- }
70-
71- override DataFlow:: Node getOptions ( ) {
72- result in [ this .getArg ( 3 ) , this .getArgByName ( "options" ) ]
73- }
74-
75- override predicate verifiesSignature ( ) {
76- // jwt.decode(token, "key", "HS256")
77- not exists ( this .getArgByName ( "verify" ) ) and not exists ( this .getOptions ( ) )
78- or
79- // jwt.decode(token, verify=False)
80- not isFalse ( this .getArgByName ( "verify" ) ) and
81- // jwt.decode(token, key, options={"verify_signature": False})
82- not exists ( KeyValuePair optionsDict , NameConstant falseName |
83- falseName .getId ( ) = "False" and
84- optionsDict = this .getArgByName ( "options" ) .asExpr ( ) .( Dict ) .getItems ( ) .getAnItem ( ) and
85- optionsDict .getKey ( ) .( Str_ ) .getS ( ) .matches ( "%verify%" ) and
86- falseName = optionsDict .getValue ( )
87- )
88- }
89- }
90- }
0 commit comments