@@ -69,22 +69,45 @@ module UntrustedToAllowOriginHeaderConfig implements DataFlow::ConfigSig {
69
69
predicate isSink ( DataFlow:: Node sink ) { isSinkHW ( sink , _) }
70
70
}
71
71
72
+ module UntrustedToAllowOriginConfigConfig implements DataFlow:: ConfigSig {
73
+ predicate isSource ( DataFlow:: Node source ) { source instanceof UntrustedFlowSource }
74
+
75
+ additional predicate isSinkWrite ( DataFlow:: Node sink , GinCors:: AllowOriginsWrite w ) {
76
+ sink = w
77
+ }
78
+
79
+ predicate isSink ( DataFlow:: Node sink ) { isSinkWrite ( sink , _) }
80
+ }
81
+
72
82
/**
73
83
* Tracks taint flowfor reasoning about when an `UntrustedFlowSource` flows to
74
84
* a `HeaderWrite` that writes an `Access-Control-Allow-Origin` header's value.
75
85
*/
76
86
module UntrustedToAllowOriginHeaderFlow = TaintTracking:: Global< UntrustedToAllowOriginHeaderConfig > ;
77
87
88
+ module UntrustedToAllowOriginConfigFlow = TaintTracking:: Global< UntrustedToAllowOriginConfigConfig > ;
89
+
78
90
/**
79
91
* Holds if the provided `allowOriginHW` HeaderWrite's parent ResponseWriter
80
92
* also has another HeaderWrite that sets a `Access-Control-Allow-Credentials`
81
93
* header to `true`.
82
94
*/
83
- predicate allowCredentialsIsSetToTrue ( AllowOriginHeaderWrite allowOriginHW ) {
95
+ predicate allowCredentialsIsSetToTrue ( DataFlow :: ExprNode allowOrigin ) {
84
96
exists ( AllowCredentialsHeaderWrite allowCredentialsHW |
85
97
allowCredentialsHW .getHeaderValue ( ) .toLowerCase ( ) = "true"
86
98
|
87
- allowOriginHW .getResponseWriter ( ) = allowCredentialsHW .getResponseWriter ( )
99
+ allowOrigin .( AllowOriginHeaderWrite ) .getResponseWriter ( ) = allowCredentialsHW .getResponseWriter ( )
100
+ )
101
+ or
102
+ exists ( GinCors:: AllowCredentialsWrite allowCredentialsGin |
103
+ allowCredentialsGin .toString ( ) = "true"
104
+ |
105
+ //flow only goes in one direction so fix this before PR
106
+ allowCredentialsGin .getConfig ( ) = allowOrigin .( GinCors:: AllowOriginsWrite ) .getConfig ( )
107
+ and
108
+ not exists ( GinCors:: AllowAllOriginsWrite allowAllOrigins |
109
+ allowAllOrigins .toString ( ) = "true" //and DataFlow::localFlow(allowCredentialsGin.getBase(), allowAllOrigins.getBase())
110
+ )
88
111
)
89
112
}
90
113
@@ -93,10 +116,12 @@ predicate allowCredentialsIsSetToTrue(AllowOriginHeaderWrite allowOriginHW) {
93
116
* UntrustedFlowSource.
94
117
* The `message` parameter is populated with the warning message to be returned by the query.
95
118
*/
96
- predicate flowsFromUntrustedToAllowOrigin ( AllowOriginHeaderWrite allowOriginHW , string message ) {
119
+ predicate flowsFromUntrustedToAllowOrigin ( DataFlow :: ExprNode allowOriginHW , string message ) {
97
120
exists ( DataFlow:: Node sink |
98
121
UntrustedToAllowOriginHeaderFlow:: flowTo ( sink ) and
99
- UntrustedToAllowOriginHeaderConfig:: isSinkHW ( sink , allowOriginHW )
122
+ UntrustedToAllowOriginHeaderConfig:: isSinkHW ( sink , allowOriginHW ) or
123
+ UntrustedToAllowOriginConfigFlow:: flowTo ( sink ) and
124
+ UntrustedToAllowOriginConfigConfig:: isSinkWrite ( sink , allowOriginHW )
100
125
|
101
126
message =
102
127
headerAllowOrigin ( ) + " header is set to a user-defined value, and " +
@@ -108,11 +133,17 @@ predicate flowsFromUntrustedToAllowOrigin(AllowOriginHeaderWrite allowOriginHW,
108
133
* Holds if the provided `allowOriginHW` HeaderWrite is for a `Access-Control-Allow-Origin`
109
134
* header and the value is set to `null`.
110
135
*/
111
- predicate allowOriginIsNull ( AllowOriginHeaderWrite allowOriginHW , string message ) {
112
- allowOriginHW .getHeaderValue ( ) .toLowerCase ( ) = "null" and
136
+ predicate allowOriginIsNull ( DataFlow :: ExprNode allowOrigin , string message ) {
137
+ allowOrigin . ( AllowOriginHeaderWrite ) .getHeaderValue ( ) .toLowerCase ( ) = "null" and
113
138
message =
114
- headerAllowOrigin ( ) + " header is set to `" + allowOriginHW .getHeaderValue ( ) + "`, and " +
139
+ headerAllowOrigin ( ) + " header is set to `" + allowOrigin . ( AllowOriginHeaderWrite ) .getHeaderValue ( ) + "`, and " +
115
140
headerAllowCredentials ( ) + " is set to `true`"
141
+ or
142
+ allowOrigin .( GinCors:: AllowOriginsWrite ) .asExpr ( ) .( SliceLit ) .getAnElement ( ) .toString ( ) .matches ( "\"null%\"" ) and
143
+ message =
144
+ headerAllowOrigin ( ) + " header is set to `" + allowOrigin .( GinCors:: AllowOriginsWrite ) .asExpr ( ) .( SliceLit ) .getAnElement ( ) .toString ( ) + "`, and " +
145
+ headerAllowCredentials ( ) + " is set to `true`"
146
+
116
147
}
117
148
118
149
/**
@@ -170,26 +201,26 @@ module FromUntrustedFlow = TaintTracking::Global<FromUntrustedConfig>;
170
201
/**
171
202
* Holds if the provided `allowOriginHW` is also destination of a `UntrustedFlowSource`.
172
203
*/
173
- predicate flowsToGuardedByCheckOnUntrusted ( AllowOriginHeaderWrite allowOriginHW ) {
204
+ predicate flowsToGuardedByCheckOnUntrusted ( DataFlow :: ExprNode allowOriginHW ) {
174
205
exists ( DataFlow:: Node sink , ControlFlow:: ConditionGuardNode cgn |
175
206
FromUntrustedFlow:: flowTo ( sink ) and FromUntrustedConfig:: isSinkCgn ( sink , cgn )
176
207
|
177
208
cgn .dominates ( allowOriginHW .getBasicBlock ( ) )
178
209
)
179
210
}
180
211
181
- from AllowOriginHeaderWrite allowOriginHW , string message
212
+ from DataFlow :: ExprNode allowOrigin , string message
182
213
where
183
- allowCredentialsIsSetToTrue ( allowOriginHW ) and
214
+ allowCredentialsIsSetToTrue ( allowOrigin ) and
184
215
(
185
- flowsFromUntrustedToAllowOrigin ( allowOriginHW , message )
216
+ flowsFromUntrustedToAllowOrigin ( allowOrigin , message )
186
217
or
187
- allowOriginIsNull ( allowOriginHW , message )
218
+ allowOriginIsNull ( allowOrigin , message )
188
219
) and
189
- not flowsToGuardedByCheckOnUntrusted ( allowOriginHW ) and
220
+ not flowsToGuardedByCheckOnUntrusted ( allowOrigin ) and
190
221
not exists ( ControlFlow:: ConditionGuardNode cgn |
191
222
cgn .ensures ( any ( AllowedFlag f ) .getAFlag ( ) .getANode ( ) , _)
192
223
|
193
- cgn .dominates ( allowOriginHW .getBasicBlock ( ) )
224
+ cgn .dominates ( allowOrigin .getBasicBlock ( ) )
194
225
)
195
- select allowOriginHW , message
226
+ select allowOrigin , message
0 commit comments