@@ -149,7 +149,7 @@ private module BrowserIdCrypto {
149149 * A model of the Node.js builtin crypto library.
150150 */
151151private module NodeJSCrypto {
152- private class InstantiatedAlgorithm extends DataFlow :: CallNode {
152+ private class InstantiatedAlgorithm extends API :: CallNode {
153153 private string algorithmName ;
154154
155155 InstantiatedAlgorithm ( ) {
@@ -166,11 +166,11 @@ private module NodeJSCrypto {
166166 * Also matches `createHash`, `createHmac`, `createSign` instead of `createCipher`.
167167 */
168168
169- exists ( DataFlow :: SourceNode mod |
170- mod = DataFlow :: moduleImport ( "crypto" ) and
171- this = mod . getAMemberCall ( "create" + [ "Hash" , "Hmac" , "Sign" , "Cipher" ] ) and
172- algorithmName = this . getArgument ( 0 ) . getStringValue ( )
173- )
169+ this =
170+ API :: moduleImport ( "crypto" )
171+ . getMember ( "create" + [ "Hash" , "Hmac" , "Sign" , "Cipher" ] )
172+ . getACall ( ) and
173+ algorithmName = this . getArgument ( 0 ) . getStringValue ( )
174174 }
175175
176176 CryptographicAlgorithm getAlgorithm ( ) { result .matchesName ( algorithmName ) }
@@ -197,13 +197,12 @@ private module NodeJSCrypto {
197197 // crypto.generateKeyPair(type, options, callback)
198198 // crypto.generateKeyPairSync(type, options)
199199 // crypto.generateKeySync(type, options)
200- exists ( DataFlow :: SourceNode mod , string keyType |
200+ exists ( string keyType |
201201 keyType = "Key" and symmetric = true
202202 or
203203 keyType = "KeyPair" and symmetric = false
204204 |
205- mod = DataFlow:: moduleImport ( "crypto" ) and
206- this = mod .getAMemberCall ( "generate" + keyType + [ "" , "Sync" ] )
205+ this = API:: moduleImport ( "crypto" ) .getMember ( "generate" + keyType + [ "" , "Sync" ] ) .getACall ( )
207206 )
208207 }
209208
@@ -249,17 +248,15 @@ private module NodeJSCrypto {
249248
250249 private class Key extends CryptographicKey {
251250 Key ( ) {
252- exists ( InstantiatedAlgorithm instantiation , string name |
253- name = "setPrivateKey" or
254- name = "sign"
255- |
256- this = instantiation . getAMethodCall ( name ) . getArgument ( 0 )
257- )
251+ this =
252+ any ( InstantiatedAlgorithm i )
253+ . getReturn ( )
254+ . getMember ( [ "setPrivateKey" , "sign" ] )
255+ . getParameter ( 0 )
256+ . asSink ( )
258257 or
259- exists ( DataFlow:: SourceNode mod , string name , DataFlow:: InvokeNode call , int index |
260- mod = DataFlow:: moduleImport ( "crypto" ) and
261- call = mod .getAMemberCall ( name ) and
262- this = call .getArgument ( index )
258+ exists ( string name , int index |
259+ this = API:: moduleImport ( "crypto" ) .getMember ( name ) .getACall ( ) .getArgument ( index )
263260 |
264261 index = 0 and
265262 ( name = "privateDecrypt" or name = "privateEncrypt" )
@@ -291,13 +288,13 @@ private module CryptoJS {
291288 * ```
292289 */
293290
294- exists ( DataFlow :: SourceNode mod , DataFlow :: PropRead propRead |
295- mod = DataFlow :: moduleImport ( "crypto-js" ) and
296- propRead = mod . getAPropertyRead ( "algo" ) . getAPropertyRead ( ) and
297- this = propRead . getAMemberCall ( "create" ) and
298- algorithmName = propRead . getPropertyName ( ) and
299- not isStrongPasswordHashingAlgorithm ( algorithmName )
300- )
291+ this =
292+ API :: moduleImport ( "crypto-js" )
293+ . getMember ( "algo" )
294+ . getMember ( algorithmName )
295+ . getMember ( "create" )
296+ . getACall ( ) and
297+ not isStrongPasswordHashingAlgorithm ( algorithmName )
301298 }
302299
303300 CryptographicAlgorithm getAlgorithm ( ) { result .matchesName ( algorithmName ) }
@@ -321,10 +318,7 @@ private module CryptoJS {
321318 */
322319 private API:: Node getAlgorithmNode ( CryptographicAlgorithm algorithm ) {
323320 exists ( string algorithmName | algorithm .matchesName ( algorithmName ) |
324- exists ( API:: Node mod | mod = API:: moduleImport ( "crypto-js" ) |
325- result = mod .getMember ( algorithmName ) or
326- result = mod .getMember ( "Hmac" + algorithmName ) // they prefix Hmac
327- )
321+ result = API:: moduleImport ( "crypto-js" ) .getMember ( [ algorithmName , "Hmac" + algorithmName ] )
328322 or
329323 result = API:: moduleImport ( "crypto-js/" + algorithmName )
330324 )
@@ -500,13 +494,12 @@ private module TweetNaCl {
500494 * Also matches the "hash" method name, and the "nacl-fast" module.
501495 */
502496
503- exists ( DataFlow :: SourceNode mod , string name |
497+ exists ( string name |
504498 name = "hash" and algorithm .matchesName ( "SHA512" )
505499 or
506500 name = "sign" and algorithm .matchesName ( "ed25519" )
507501 |
508- ( mod = DataFlow:: moduleImport ( "nacl" ) or mod = DataFlow:: moduleImport ( "nacl-fast" ) ) and
509- this = mod .getAMemberCall ( name ) and
502+ this = API:: moduleImport ( [ "nacl" , "nacl-fast" ] ) .getMember ( name ) .getACall ( ) and
510503 super .getArgument ( 0 ) = input
511504 )
512505 }
@@ -532,17 +525,13 @@ private module HashJs {
532525 */
533526 private DataFlow:: CallNode getAlgorithmNode ( CryptographicAlgorithm algorithm ) {
534527 exists ( string algorithmName | algorithm .matchesName ( algorithmName ) |
535- result = DataFlow :: moduleMember ( "hash.js" , algorithmName ) .getACall ( )
528+ result = API :: moduleImport ( "hash.js" ) . getMember ( algorithmName ) .getACall ( )
536529 or
537- exists ( DataFlow:: SourceNode mod |
538- mod = DataFlow:: moduleImport ( "hash.js/lib/hash/" + algorithmName )
539- or
540- exists ( string size |
541- mod = DataFlow:: moduleImport ( "hash.js/lib/hash/sha/" + size ) and
542- algorithmName = "SHA" + size
543- )
544- |
545- result = mod .getACall ( )
530+ result = API:: moduleImport ( "hash.js/lib/hash/" + algorithmName ) .getACall ( )
531+ or
532+ exists ( string size |
533+ result = API:: moduleImport ( "hash.js/lib/hash/sha/" + size ) .getACall ( ) and
534+ algorithmName = "SHA" + size
546535 )
547536 )
548537 }
@@ -582,10 +571,7 @@ private module HashJs {
582571 * A model of the forge library.
583572 */
584573private module Forge {
585- private DataFlow:: SourceNode getAnImportNode ( ) {
586- result = DataFlow:: moduleImport ( "forge" ) or
587- result = DataFlow:: moduleImport ( "node-forge" )
588- }
574+ private API:: Node getAnImportNode ( ) { result = API:: moduleImport ( [ "forge" , "node-forge" ] ) }
589575
590576 abstract private class Cipher extends DataFlow:: CallNode {
591577 abstract CryptographicAlgorithm getAlgorithm ( ) ;
@@ -597,14 +583,14 @@ private module Forge {
597583 private string blockModeString ;
598584
599585 KeyCipher ( ) {
600- exists ( DataFlow:: SourceNode mod , string algorithmName |
601- mod = getAnImportNode ( ) and
602- algorithm .matchesName ( algorithmName )
603- |
604- exists ( string createName , string cipherName , string cipherPrefix |
586+ exists ( string algorithmName | algorithm .matchesName ( algorithmName ) |
587+ exists ( string cipherName , string cipherPrefix |
605588 // `require('forge').cipher.createCipher("3DES-CBC").update("secret", "key");`
606- ( createName = "createCipher" or createName = "createDecipher" ) and
607- this = mod .getAPropertyRead ( "cipher" ) .getAMemberCall ( createName ) and
589+ this =
590+ getAnImportNode ( )
591+ .getMember ( "cipher" )
592+ .getMember ( [ "createCipher" , "createDecipher" ] )
593+ .getACall ( ) and
608594 this .getArgument ( 0 ) .mayHaveStringValue ( cipherName ) and
609595 cipherName = cipherPrefix + "-" + blockModeString and
610596 blockModeString = [ "CBC" , "CFB" , "CTR" , "ECB" , "GCM" , "OFB" ] and
@@ -613,13 +599,13 @@ private module Forge {
613599 )
614600 or
615601 // `require("forge").rc2.createEncryptionCipher("key").update("secret");`
616- exists ( string createName |
617- createName = "createEncryptionCipher" or createName = "createDecryptionCipher"
618- |
619- this = mod . getAPropertyRead ( algorithmName ) . getAMemberCall ( createName ) and
620- key = this . getArgument ( 0 ) and
621- blockModeString = algorithmName
622- )
602+ this =
603+ getAnImportNode ( )
604+ . getMember ( algorithmName )
605+ . getMember ( [ "createEncryptionCipher" , "createDecryptionCipher" ] )
606+ . getACall ( ) and
607+ key = this . getArgument ( 0 ) and
608+ blockModeString = algorithmName
623609 )
624610 }
625611
@@ -640,10 +626,7 @@ private module Forge {
640626 exists ( string algorithmName | algorithm .matchesName ( algorithmName ) |
641627 // require("forge").md.md5.create().update('The quick brown fox jumps over the lazy dog');
642628 this =
643- getAnImportNode ( )
644- .getAPropertyRead ( "md" )
645- .getAPropertyRead ( algorithmName )
646- .getAMemberCall ( "create" )
629+ getAnImportNode ( ) .getMember ( "md" ) .getMember ( algorithmName ) .getMember ( "create" ) .getACall ( )
647630 )
648631 }
649632
@@ -679,15 +662,17 @@ private module Forge {
679662 // var cipher = forge.rc2.createEncryptionCipher(key, 128);
680663 this =
681664 getAnImportNode ( )
682- .getAPropertyRead ( any ( string s | algorithm .matchesName ( s ) ) )
683- .getAMemberCall ( "createEncryptionCipher" )
665+ .getMember ( any ( string s | algorithm .matchesName ( s ) ) )
666+ .getMember ( "createEncryptionCipher" )
667+ .getACall ( )
684668 or
685669 // var key = forge.random.getBytesSync(16);
686670 // var cipher = forge.cipher.createCipher('AES-CBC', key);
687671 this =
688672 getAnImportNode ( )
689- .getAPropertyRead ( "cipher" )
690- .getAMemberCall ( [ "createCipher" , "createDecipher" ] ) and
673+ .getMember ( "cipher" )
674+ .getMember ( [ "createCipher" , "createDecipher" ] )
675+ .getACall ( ) and
691676 algorithm .matchesName ( this .getArgument ( 0 ) .getStringValue ( ) )
692677 }
693678
@@ -716,12 +701,9 @@ private module Md5 {
716701
717702 Apply ( ) {
718703 // `require("md5")("message");`
719- exists ( DataFlow:: SourceNode mod |
720- mod = DataFlow:: moduleImport ( "md5" ) and
721- algorithm .matchesName ( "MD5" ) and
722- this = mod .getACall ( ) and
723- super .getArgument ( 0 ) = input
724- )
704+ algorithm .matchesName ( "MD5" ) and
705+ this = API:: moduleImport ( "md5" ) .getACall ( ) and
706+ super .getArgument ( 0 ) = input
725707 }
726708
727709 override DataFlow:: Node getAnInput ( ) { result = input }
@@ -743,21 +725,12 @@ private module Bcrypt {
743725
744726 Apply ( ) {
745727 // `require("bcrypt").hash(password);` with minor naming variations
746- exists ( DataFlow:: SourceNode mod , string moduleName , string methodName |
747- algorithm .matchesName ( "BCRYPT" ) and
748- (
749- moduleName = "bcrypt" or
750- moduleName = "bcryptjs" or
751- moduleName = "bcrypt-nodejs"
752- ) and
753- (
754- methodName = "hash" or
755- methodName = "hashSync"
756- ) and
757- mod = DataFlow:: moduleImport ( moduleName ) and
758- this = mod .getAMemberCall ( methodName ) and
759- super .getArgument ( 0 ) = input
760- )
728+ algorithm .matchesName ( "BCRYPT" ) and
729+ this =
730+ API:: moduleImport ( [ "bcrypt" , "bcryptjs" , "bcrypt-nodejs" ] )
731+ .getMember ( [ "hash" , "hashSync" ] )
732+ .getACall ( ) and
733+ super .getArgument ( 0 ) = input
761734 }
762735
763736 override DataFlow:: Node getAnInput ( ) { result = input }
@@ -779,13 +752,11 @@ private module Hasha {
779752
780753 Apply ( ) {
781754 // `require('hasha')('unicorn', { algorithm: "md5" });`
782- exists ( DataFlow:: SourceNode mod , string algorithmName , DataFlow:: Node algorithmNameNode |
783- mod = DataFlow:: moduleImport ( "hasha" ) and
784- this = mod .getACall ( ) and
755+ exists ( string algorithmName |
756+ this = API:: moduleImport ( "hasha" ) .getACall ( ) and
785757 super .getArgument ( 0 ) = input and
786758 algorithm .matchesName ( algorithmName ) and
787- super .getOptionArgument ( 1 , "algorithm" ) = algorithmNameNode and
788- algorithmNameNode .mayHaveStringValue ( algorithmName )
759+ super .getOptionArgument ( 1 , "algorithm" ) .mayHaveStringValue ( algorithmName )
789760 )
790761 }
791762
@@ -803,7 +774,7 @@ private module Hasha {
803774 */
804775private module ExpressJwt {
805776 private class Key extends CryptographicKey {
806- Key ( ) { this = DataFlow :: moduleMember ( "express-jwt" , "sign" ) .getACall ( ) .getArgument ( 1 ) }
777+ Key ( ) { this = API :: moduleImport ( "express-jwt" ) . getMember ( "sign" ) .getACall ( ) .getArgument ( 1 ) }
807778 }
808779}
809780
0 commit comments