@@ -30,39 +30,50 @@ module InsecureRandomness {
30
30
override InvokeExpr astNode ;
31
31
32
32
DefaultSource ( ) {
33
- exists ( DataFlow:: ModuleImportNode mod , string name | mod .getPath ( ) = name |
34
- // require("random-number")();
35
- name = "random-number" and
36
- this = mod .getACall ( )
33
+ not this .getContainer ( ) = getASecureRandomGeneratingFunction ( ) and
34
+ (
35
+ exists ( DataFlow:: ModuleImportNode mod , string name | mod .getPath ( ) = name |
36
+ // require("random-number")();
37
+ name = "random-number" and
38
+ this = mod .getACall ( )
39
+ or
40
+ // require("random-int")();
41
+ name = "random-int" and
42
+ this = mod .getACall ( )
43
+ or
44
+ // require("random-float")();
45
+ name = "random-float" and
46
+ this = mod .getACall ( )
47
+ or
48
+ // require('random-seed').create()();
49
+ name = "random-seed" and
50
+ this = mod .getAMemberCall ( "create" ) .getACall ( )
51
+ or
52
+ // require('unique-random')()();
53
+ name = "unique-random" and
54
+ this = mod .getACall ( ) .getACall ( )
55
+ )
37
56
or
38
- // require("random-int")();
39
- name = "random-int" and
40
- this = mod .getACall ( )
57
+ // Math.random()
58
+ this = DataFlow:: globalVarRef ( "Math" ) .getAMemberCall ( "random" )
41
59
or
42
- // require("random-float")();
43
- name = "random-float" and
44
- this = mod .getACall ( )
60
+ // (new require('chance')).<name>()
61
+ this = DataFlow:: moduleImport ( "chance" ) .getAnInstantiation ( ) .getAMemberInvocation ( _)
45
62
or
46
- // require('random-seed').create()();
47
- name = "random-seed" and
48
- this = mod .getAMemberCall ( "create" ) .getACall ( )
49
- or
50
- // require('unique-random')()();
51
- name = "unique-random" and
52
- this = mod .getACall ( ) .getACall ( )
63
+ // require('crypto').pseudoRandomBytes()
64
+ this = DataFlow:: moduleMember ( "crypto" , "pseudoRandomBytes" ) .getAnInvocation ( )
53
65
)
54
- or
55
- // Math.random()
56
- this = DataFlow:: globalVarRef ( "Math" ) .getAMemberCall ( "random" )
57
- or
58
- // (new require('chance')).<name>()
59
- this = DataFlow:: moduleImport ( "chance" ) .getAnInstantiation ( ) .getAMemberInvocation ( _)
60
- or
61
- // require('crypto').pseudoRandomBytes()
62
- this = DataFlow:: moduleMember ( "crypto" , "pseudoRandomBytes" ) .getAnInvocation ( )
63
66
}
64
67
}
65
68
69
+ /**
70
+ * Gets a container that at some point generates a secure random value.
71
+ */
72
+ pragma [ noinline]
73
+ private StmtContainer getASecureRandomGeneratingFunction ( ) {
74
+ result = randomBufferSource ( ) .getContainer ( )
75
+ }
76
+
66
77
/**
67
78
* A sensitive write, considered as a sink for random values that are not cryptographically
68
79
* secure.
@@ -94,4 +105,24 @@ module InsecureRandomness {
94
105
succ = mc
95
106
)
96
107
}
108
+
109
+ /**
110
+ * Gets a Buffer/TypedArray containing cryptographically secure random numbers.
111
+ */
112
+ DataFlow:: SourceNode randomBufferSource ( ) {
113
+ result = DataFlow:: moduleMember ( "crypto" , [ "randomBytes" , "randomFillSync" ] ) .getACall ( )
114
+ or
115
+ exists ( DataFlow:: CallNode call |
116
+ call = DataFlow:: moduleMember ( "crypto" , [ "randomFill" , "randomFillSync" ] ) and
117
+ result = call .getArgument ( 0 ) .getALocalSource ( )
118
+ )
119
+ or
120
+ result = DataFlow:: globalVarRef ( "crypto" ) .getAMethodCall ( "getRandomValues" )
121
+ or
122
+ result = DataFlow:: moduleImport ( "secure-random" ) .getACall ( )
123
+ or
124
+ result =
125
+ DataFlow:: moduleImport ( "secure-random" )
126
+ .getAMethodCall ( [ "randomArray" , "randomUint8Array" , "randomBuffer" ] )
127
+ }
97
128
}
0 commit comments