@@ -2669,6 +2669,7 @@ private module StdlibPrivate {
26692669
26702670 HashlibNewCall ( ) {
26712671 this = hashlibNewCall ( hashName ) and
2672+ // we only want to consider it as an cryptographic operation if the input is available
26722673 exists ( this .getParameter ( 1 , "data" ) )
26732674 }
26742675
@@ -2751,6 +2752,78 @@ private module StdlibPrivate {
27512752 }
27522753 }
27532754
2755+ // ---------------------------------------------------------------------------
2756+ // hmac
2757+ // ---------------------------------------------------------------------------
2758+ abstract class HmacCryptographicOperation extends Cryptography:: CryptographicOperation:: Range ,
2759+ API:: CallNode {
2760+ abstract API:: Node getDigestArg ( ) ;
2761+
2762+ override Cryptography:: CryptographicAlgorithm getAlgorithm ( ) {
2763+ exists ( string algorithmName | result .matchesName ( algorithmName ) |
2764+ this .getDigestArg ( ) .asSink ( ) = hashlibMember ( algorithmName ) .asSource ( )
2765+ or
2766+ this .getDigestArg ( ) .getAValueReachingSink ( ) .asExpr ( ) .( StrConst ) .getText ( ) = algorithmName
2767+ )
2768+ }
2769+
2770+ override Cryptography:: BlockMode getBlockMode ( ) { none ( ) }
2771+ }
2772+
2773+ API:: CallNode getHmacConstructorCall ( API:: Node digestArg ) {
2774+ result = API:: moduleImport ( "hmac" ) .getMember ( [ "new" , "HMAC" ] ) .getACall ( ) and
2775+ digestArg = result .getParameter ( 2 , "digestmod" )
2776+ }
2777+
2778+ /**
2779+ * A call to `hmac.new`/`hmac.HMAC`.
2780+ *
2781+ * See https://docs.python.org/3.11/library/hmac.html#hmac.new
2782+ */
2783+ class HmacNewCall extends HmacCryptographicOperation {
2784+ API:: Node digestArg ;
2785+
2786+ HmacNewCall ( ) {
2787+ this = getHmacConstructorCall ( digestArg ) and
2788+ // we only want to consider it as an cryptographic operation if the input is available
2789+ exists ( this .getParameter ( 1 , "msg" ) .asSink ( ) )
2790+ }
2791+
2792+ override API:: Node getDigestArg ( ) { result = digestArg }
2793+
2794+ override DataFlow:: Node getAnInput ( ) { result = this .getParameter ( 1 , "msg" ) .asSink ( ) }
2795+ }
2796+
2797+ /**
2798+ * A call to `.update` on an HMAC object.
2799+ *
2800+ * See https://docs.python.org/3.11/library/hmac.html#hmac.HMAC.update
2801+ */
2802+ class HmacUpdateCall extends HmacCryptographicOperation {
2803+ API:: Node digestArg ;
2804+
2805+ HmacUpdateCall ( ) {
2806+ this = getHmacConstructorCall ( digestArg ) .getReturn ( ) .getMember ( "update" ) .getACall ( )
2807+ }
2808+
2809+ override API:: Node getDigestArg ( ) { result = digestArg }
2810+
2811+ override DataFlow:: Node getAnInput ( ) { result = this .getParameter ( 0 , "msg" ) .asSink ( ) }
2812+ }
2813+
2814+ /**
2815+ * A call to `hmac.digest`.
2816+ *
2817+ * See https://docs.python.org/3.11/library/hmac.html#hmac.digest
2818+ */
2819+ class HmacDigestCall extends HmacCryptographicOperation {
2820+ HmacDigestCall ( ) { this = API:: moduleImport ( "hmac" ) .getMember ( "digest" ) .getACall ( ) }
2821+
2822+ override API:: Node getDigestArg ( ) { result = this .getParameter ( 2 , "digest" ) }
2823+
2824+ override DataFlow:: Node getAnInput ( ) { result = this .getParameter ( 1 , "msg" ) .asSink ( ) }
2825+ }
2826+
27542827 // ---------------------------------------------------------------------------
27552828 // logging
27562829 // ---------------------------------------------------------------------------
0 commit comments