@@ -8,11 +8,11 @@ import semmle.javascript.security.CryptoAlgorithms
8
8
/**
9
9
* An application of a cryptographic algorithm.
10
10
*/
11
- abstract class CryptographicOperation extends Expr {
11
+ abstract class CryptographicOperation extends DataFlow :: Node {
12
12
/**
13
13
* Gets the input the algorithm is used on, e.g. the plain text input to be encrypted.
14
14
*/
15
- abstract Expr getInput ( ) ;
15
+ abstract DataFlow :: Node getInput ( ) ;
16
16
17
17
/**
18
18
* Gets the applied algorithm.
@@ -58,8 +58,8 @@ class CryptographicKeyCredentialsExpr extends CredentialsExpr {
58
58
* A model of the asmCrypto library.
59
59
*/
60
60
private module AsmCrypto {
61
- private class Apply extends CryptographicOperation {
62
- Expr input ;
61
+ private class Apply extends CryptographicOperation instanceof DataFlow :: CallNode {
62
+ DataFlow :: Node input ;
63
63
CryptographicAlgorithm algorithm ; // non-functional
64
64
65
65
Apply ( ) {
@@ -73,17 +73,15 @@ private module AsmCrypto {
73
73
* ```
74
74
*/
75
75
76
- exists ( DataFlow:: CallNode mce | this = mce .asExpr ( ) |
77
- exists ( DataFlow:: SourceNode asmCrypto , string algorithmName |
78
- asmCrypto = DataFlow:: globalVarRef ( "asmCrypto" ) and
79
- algorithm .matchesName ( algorithmName ) and
80
- mce = asmCrypto .getAPropertyRead ( algorithmName ) .getAMemberCall ( _) and
81
- input = mce .getAnArgument ( ) .asExpr ( )
82
- )
76
+ exists ( DataFlow:: SourceNode asmCrypto , string algorithmName |
77
+ asmCrypto = DataFlow:: globalVarRef ( "asmCrypto" ) and
78
+ algorithm .matchesName ( algorithmName ) and
79
+ this = asmCrypto .getAPropertyRead ( algorithmName ) .getAMemberCall ( _) and
80
+ input = this .getAnArgument ( )
83
81
)
84
82
}
85
83
86
- override Expr getInput ( ) { result = input }
84
+ override DataFlow :: Node getInput ( ) { result = input }
87
85
88
86
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
89
87
}
@@ -97,9 +95,8 @@ private module BrowserIdCrypto {
97
95
Key ( ) { this = any ( Apply apply ) .getKey ( ) }
98
96
}
99
97
100
- private class Apply extends CryptographicOperation {
98
+ private class Apply extends CryptographicOperation instanceof DataFlow :: MethodCallNode {
101
99
CryptographicAlgorithm algorithm ; // non-functional
102
- MethodCallExpr mce ;
103
100
104
101
Apply ( ) {
105
102
/*
@@ -118,7 +115,6 @@ private module BrowserIdCrypto {
118
115
* ```
119
116
*/
120
117
121
- this = mce and
122
118
exists (
123
119
DataFlow:: SourceNode mod , DataFlow:: Node algorithmNameNode , DataFlow:: CallNode keygen ,
124
120
DataFlow:: FunctionNode callback
@@ -128,15 +124,15 @@ private module BrowserIdCrypto {
128
124
algorithmNameNode = keygen .getOptionArgument ( 0 , "algorithm" ) and
129
125
algorithm .matchesName ( algorithmNameNode .getStringValue ( ) ) and
130
126
callback = keygen .getCallback ( 1 ) and
131
- this = mod .getAMemberCall ( "sign" ) . asExpr ( )
127
+ this = mod .getAMemberCall ( "sign" )
132
128
)
133
129
}
134
130
135
- override Expr getInput ( ) { result = mce .getArgument ( 0 ) }
131
+ override DataFlow :: Node getInput ( ) { result = super .getArgument ( 0 ) }
136
132
137
133
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
138
134
139
- DataFlow:: Node getKey ( ) { result . asExpr ( ) = mce .getArgument ( 1 ) }
135
+ DataFlow:: Node getKey ( ) { result = super .getArgument ( 1 ) }
140
136
}
141
137
}
142
138
@@ -217,14 +213,12 @@ private module NodeJSCrypto {
217
213
override predicate isSymmetricKey ( ) { none ( ) }
218
214
}
219
215
220
- private class Apply extends CryptographicOperation , MethodCallExpr {
216
+ private class Apply extends CryptographicOperation instanceof DataFlow :: MethodCallNode {
221
217
InstantiatedAlgorithm instantiation ;
222
218
223
- Apply ( ) {
224
- this = instantiation .getAMethodCall ( any ( string m | m = "update" or m = "write" ) ) .asExpr ( )
225
- }
219
+ Apply ( ) { this = instantiation .getAMethodCall ( any ( string m | m = "update" or m = "write" ) ) }
226
220
227
- override Expr getInput ( ) { result = this .getArgument ( 0 ) }
221
+ override DataFlow :: Node getInput ( ) { result = super .getArgument ( 0 ) }
228
222
229
223
override CryptographicAlgorithm getAlgorithm ( ) { result = instantiation .getAlgorithm ( ) }
230
224
}
@@ -260,7 +254,7 @@ private module CryptoJS {
260
254
/**
261
255
* Matches `CryptoJS.<algorithmName>` and `require("crypto-js/<algorithmName>")`
262
256
*/
263
- private DataFlow:: SourceNode getAlgorithmExpr ( CryptographicAlgorithm algorithm ) {
257
+ private DataFlow:: SourceNode getAlgorithmNode ( CryptographicAlgorithm algorithm ) {
264
258
exists ( string algorithmName | algorithm .matchesName ( algorithmName ) |
265
259
exists ( DataFlow:: SourceNode mod | mod = DataFlow:: moduleImport ( "crypto-js" ) |
266
260
result = mod .getAPropertyRead ( algorithmName ) or
@@ -274,7 +268,9 @@ private module CryptoJS {
274
268
)
275
269
}
276
270
277
- private DataFlow:: CallNode getEncryptionApplication ( Expr input , CryptographicAlgorithm algorithm ) {
271
+ private DataFlow:: CallNode getEncryptionApplication (
272
+ DataFlow:: Node input , CryptographicAlgorithm algorithm
273
+ ) {
278
274
/*
279
275
* ```
280
276
* var CryptoJS = require("crypto-js");
@@ -288,11 +284,13 @@ private module CryptoJS {
288
284
* Also matches where `CryptoJS.<algorithmName>` has been replaced by `require("crypto-js/<algorithmName>")`
289
285
*/
290
286
291
- result = getAlgorithmExpr ( algorithm ) .getAMemberCall ( "encrypt" ) and
292
- input = result .getArgument ( 0 ) . asExpr ( )
287
+ result = getAlgorithmNode ( algorithm ) .getAMemberCall ( "encrypt" ) and
288
+ input = result .getArgument ( 0 )
293
289
}
294
290
295
- private DataFlow:: CallNode getDirectApplication ( Expr input , CryptographicAlgorithm algorithm ) {
291
+ private DataFlow:: CallNode getDirectApplication (
292
+ DataFlow:: Node input , CryptographicAlgorithm algorithm
293
+ ) {
296
294
/*
297
295
* ```
298
296
* var CryptoJS = require("crypto-js");
@@ -307,28 +305,28 @@ private module CryptoJS {
307
305
* Also matches where `CryptoJS.<algorithmName>` has been replaced by `require("crypto-js/<algorithmName>")`
308
306
*/
309
307
310
- result = getAlgorithmExpr ( algorithm ) .getACall ( ) and
311
- input = result .getArgument ( 0 ) . asExpr ( )
308
+ result = getAlgorithmNode ( algorithm ) .getACall ( ) and
309
+ input = result .getArgument ( 0 )
312
310
}
313
311
314
312
private class Apply extends CryptographicOperation {
315
- Expr input ;
313
+ DataFlow :: Node input ;
316
314
CryptographicAlgorithm algorithm ; // non-functional
317
315
318
316
Apply ( ) {
319
- this = getEncryptionApplication ( input , algorithm ) . asExpr ( ) or
320
- this = getDirectApplication ( input , algorithm ) . asExpr ( )
317
+ this = getEncryptionApplication ( input , algorithm ) or
318
+ this = getDirectApplication ( input , algorithm )
321
319
}
322
320
323
- override Expr getInput ( ) { result = input }
321
+ override DataFlow :: Node getInput ( ) { result = input }
324
322
325
323
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
326
324
}
327
325
328
326
private class Key extends CryptographicKey {
329
327
Key ( ) {
330
328
exists ( DataFlow:: SourceNode e , CryptographicAlgorithm algorithm |
331
- e = getAlgorithmExpr ( algorithm )
329
+ e = getAlgorithmNode ( algorithm )
332
330
|
333
331
exists ( string name |
334
332
name = "encrypt" or
@@ -351,7 +349,7 @@ private module CryptoJS {
351
349
CreateKey ( ) {
352
350
// var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 });
353
351
this =
354
- getAlgorithmExpr ( any ( CryptographicAlgorithm algo | algo .getName ( ) = algorithm ) ) .getACall ( ) and
352
+ getAlgorithmNode ( any ( CryptographicAlgorithm algo | algo .getName ( ) = algorithm ) ) .getACall ( ) and
355
353
optionArg = 2
356
354
or
357
355
// var key = CryptoJS.algo.PBKDF2.create({ keySize: 8 });
@@ -378,8 +376,8 @@ private module CryptoJS {
378
376
* A model of the TweetNaCl library.
379
377
*/
380
378
private module TweetNaCl {
381
- private class Apply extends CryptographicOperation instanceof MethodCallExpr {
382
- Expr input ;
379
+ private class Apply extends CryptographicOperation instanceof DataFlow :: CallNode {
380
+ DataFlow :: Node input ;
383
381
CryptographicAlgorithm algorithm ;
384
382
385
383
Apply ( ) {
@@ -400,12 +398,12 @@ private module TweetNaCl {
400
398
name = "sign" and algorithm .matchesName ( "ed25519" )
401
399
|
402
400
( mod = DataFlow:: moduleImport ( "nacl" ) or mod = DataFlow:: moduleImport ( "nacl-fast" ) ) and
403
- this = mod .getAMemberCall ( name ) . asExpr ( ) and
401
+ this = mod .getAMemberCall ( name ) and
404
402
super .getArgument ( 0 ) = input
405
403
)
406
404
}
407
405
408
- override Expr getInput ( ) { result = input }
406
+ override DataFlow :: Node getInput ( ) { result = input }
409
407
410
408
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
411
409
}
@@ -421,7 +419,7 @@ private module HashJs {
421
419
* - `require("hash.js/lib/hash/<algorithmName>")`()
422
420
* - `require("hash.js/lib/hash/sha/<sha-algorithm-suffix>")`()
423
421
*/
424
- private DataFlow:: CallNode getAlgorithmExpr ( CryptographicAlgorithm algorithm ) {
422
+ private DataFlow:: CallNode getAlgorithmNode ( CryptographicAlgorithm algorithm ) {
425
423
exists ( string algorithmName | algorithm .matchesName ( algorithmName ) |
426
424
result = DataFlow:: moduleMember ( "hash.js" , algorithmName ) .getACall ( )
427
425
or
@@ -438,8 +436,8 @@ private module HashJs {
438
436
)
439
437
}
440
438
441
- private class Apply extends CryptographicOperation instanceof MethodCallExpr {
442
- Expr input ;
439
+ private class Apply extends CryptographicOperation instanceof DataFlow :: CallNode {
440
+ DataFlow :: Node input ;
443
441
CryptographicAlgorithm algorithm ; // non-functional
444
442
445
443
Apply ( ) {
@@ -456,11 +454,11 @@ private module HashJs {
456
454
* Also matches where `hash.<algorithmName>()` has been replaced by a more specific require a la `require("hash.js/lib/hash/sha/512")`
457
455
*/
458
456
459
- this = getAlgorithmExpr ( algorithm ) .getAMemberCall ( "update" ) . asExpr ( ) and
457
+ this = getAlgorithmNode ( algorithm ) .getAMemberCall ( "update" ) and
460
458
input = super .getArgument ( 0 )
461
459
}
462
460
463
- override Expr getInput ( ) { result = input }
461
+ override DataFlow :: Node getInput ( ) { result = input }
464
462
465
463
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
466
464
}
@@ -492,7 +490,7 @@ private module Forge {
492
490
// `require('forge').cipher.createCipher("3DES-CBC").update("secret", "key");`
493
491
( createName = "createCipher" or createName = "createDecipher" ) and
494
492
this = mod .getAPropertyRead ( "cipher" ) .getAMemberCall ( createName ) and
495
- this .getArgument ( 0 ) .asExpr ( ) . mayHaveStringValue ( cipherName ) and
493
+ this .getArgument ( 0 ) .mayHaveStringValue ( cipherName ) and
496
494
cipherName = cipherPrefix + "-" + cipherSuffix and
497
495
cipherSuffix = [ "CBC" , "CFB" , "CTR" , "ECB" , "GCM" , "OFB" ] and
498
496
algorithmName = cipherPrefix and
@@ -531,19 +529,19 @@ private module Forge {
531
529
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
532
530
}
533
531
534
- private class Apply extends CryptographicOperation instanceof MethodCallExpr {
535
- Expr input ;
532
+ private class Apply extends CryptographicOperation instanceof DataFlow :: CallNode {
533
+ DataFlow :: Node input ;
536
534
CryptographicAlgorithm algorithm ; // non-functional
537
535
538
536
Apply ( ) {
539
537
exists ( Cipher cipher |
540
- this = cipher .getAMemberCall ( "update" ) . asExpr ( ) and
538
+ this = cipher .getAMemberCall ( "update" ) and
541
539
super .getArgument ( 0 ) = input and
542
540
algorithm = cipher .getAlgorithm ( )
543
541
)
544
542
}
545
543
546
- override Expr getInput ( ) { result = input }
544
+ override DataFlow :: Node getInput ( ) { result = input }
547
545
548
546
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
549
547
}
@@ -590,21 +588,21 @@ private module Forge {
590
588
* A model of the md5 library.
591
589
*/
592
590
private module Md5 {
593
- private class Apply extends CryptographicOperation instanceof CallExpr {
594
- Expr input ;
591
+ private class Apply extends CryptographicOperation instanceof DataFlow :: CallNode {
592
+ DataFlow :: Node input ;
595
593
CryptographicAlgorithm algorithm ;
596
594
597
595
Apply ( ) {
598
596
// `require("md5")("message");`
599
597
exists ( DataFlow:: SourceNode mod |
600
598
mod = DataFlow:: moduleImport ( "md5" ) and
601
599
algorithm .matchesName ( "MD5" ) and
602
- this = mod .getACall ( ) . asExpr ( ) and
600
+ this = mod .getACall ( ) and
603
601
super .getArgument ( 0 ) = input
604
602
)
605
603
}
606
604
607
- override Expr getInput ( ) { result = input }
605
+ override DataFlow :: Node getInput ( ) { result = input }
608
606
609
607
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
610
608
}
@@ -614,8 +612,8 @@ private module Md5 {
614
612
* A model of the bcrypt, bcryptjs, bcrypt-nodejs libraries.
615
613
*/
616
614
private module Bcrypt {
617
- private class Apply extends CryptographicOperation instanceof MethodCallExpr {
618
- Expr input ;
615
+ private class Apply extends CryptographicOperation instanceof DataFlow :: CallNode {
616
+ DataFlow :: Node input ;
619
617
CryptographicAlgorithm algorithm ;
620
618
621
619
Apply ( ) {
@@ -632,12 +630,12 @@ private module Bcrypt {
632
630
methodName = "hashSync"
633
631
) and
634
632
mod = DataFlow:: moduleImport ( moduleName ) and
635
- this = mod .getAMemberCall ( methodName ) . asExpr ( ) and
633
+ this = mod .getAMemberCall ( methodName ) and
636
634
super .getArgument ( 0 ) = input
637
635
)
638
636
}
639
637
640
- override Expr getInput ( ) { result = input }
638
+ override DataFlow :: Node getInput ( ) { result = input }
641
639
642
640
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
643
641
}
@@ -647,23 +645,23 @@ private module Bcrypt {
647
645
* A model of the hasha library.
648
646
*/
649
647
private module Hasha {
650
- private class Apply extends CryptographicOperation instanceof CallExpr {
651
- Expr input ;
648
+ private class Apply extends CryptographicOperation instanceof DataFlow :: CallNode {
649
+ DataFlow :: Node input ;
652
650
CryptographicAlgorithm algorithm ;
653
651
654
652
Apply ( ) {
655
653
// `require('hasha')('unicorn', { algorithm: "md5" });`
656
- exists ( DataFlow:: SourceNode mod , string algorithmName , Expr algorithmNameNode |
654
+ exists ( DataFlow:: SourceNode mod , string algorithmName , DataFlow :: Node algorithmNameNode |
657
655
mod = DataFlow:: moduleImport ( "hasha" ) and
658
- this = mod .getACall ( ) . asExpr ( ) and
656
+ this = mod .getACall ( ) and
659
657
super .getArgument ( 0 ) = input and
660
658
algorithm .matchesName ( algorithmName ) and
661
- super .hasOptionArgument ( 1 , "algorithm" , algorithmNameNode ) and
659
+ super .getOptionArgument ( 1 , "algorithm" ) = algorithmNameNode and
662
660
algorithmNameNode .mayHaveStringValue ( algorithmName )
663
661
)
664
662
}
665
663
666
- override Expr getInput ( ) { result = input }
664
+ override DataFlow :: Node getInput ( ) { result = input }
667
665
668
666
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
669
667
}
0 commit comments