Skip to content

Commit f976eeb

Browse files
committed
C#: Re-factor on AppendCookieTracking to use the new API.
1 parent 1b128a2 commit f976eeb

File tree

3 files changed

+90
-6
lines changed

3 files changed

+90
-6
lines changed

csharp/ql/src/experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ where
3636
iResponse.getAppendMethod() = mc.getTarget() and
3737
isCookieWithSensitiveName(mc.getArgument(0)) and
3838
// there is no callback `OnAppendCookie` that sets `HttpOnly` to true
39-
not exists(OnAppendCookieHttpOnlyTrackingConfig config | config.hasFlowTo(_)) and
39+
not OnAppendCookieHttpOnlyTracking::flowTo(_) and
4040
// Passed as third argument to `IResponseCookies.Append`
4141
exists(DataFlow::Node creation, DataFlow::Node append |
4242
CookieOptionsTracking::flow(creation, append) and
@@ -67,7 +67,7 @@ where
6767
// default is not configured or is not set to `Always`
6868
not getAValueForCookiePolicyProp("HttpOnly").getValue() = "1" and
6969
// there is no callback `OnAppendCookie` that sets `HttpOnly` to true
70-
not exists(OnAppendCookieHttpOnlyTrackingConfig config | config.hasFlowTo(_)) and
70+
not OnAppendCookieHttpOnlyTracking::flowTo(_) and
7171
iResponse.getAppendMethod() = mc.getTarget() and
7272
isCookieWithSensitiveName(mc.getArgument(0)) and
7373
(

csharp/ql/src/experimental/Security Features/CWE-614/CookieWithoutSecure.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ where
3030
getAValueForCookiePolicyProp("Secure").getValue() = "1"
3131
) and
3232
// there is no callback `OnAppendCookie` that sets `Secure` to true
33-
not exists(OnAppendCookieSecureTrackingConfig config | config.hasFlowTo(_)) and
33+
not OnAppendCookieSecureTracking::flowTo(_) and
3434
(
3535
// `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
3636
exists(ObjectCreation oc |
@@ -80,7 +80,7 @@ where
8080
or
8181
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
8282
// there is no callback `OnAppendCookie` that sets `Secure` to true
83-
not exists(OnAppendCookieSecureTrackingConfig config | config.hasFlowTo(_)) and
83+
not OnAppendCookieSecureTracking::flowTo(_) and
8484
// the cookie option is passed to `Append`
8585
exists(DataFlow::Node creation |
8686
CookieOptionsTracking::flow(creation, _) and

csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,22 @@ Expr getAValueForProp(ObjectCreation create, Assignment a, string prop) {
135135
predicate isPropertySet(ObjectCreation oc, string prop) { exists(getAValueForProp(oc, _, prop)) }
136136

137137
/**
138+
* DEPRECATED: Use `OnAppendCookieSecureTracking` instead.
139+
*
138140
* Tracks if a callback used in `OnAppendCookie` sets `Secure` to `true`.
139141
*/
140-
class OnAppendCookieSecureTrackingConfig extends OnAppendCookieTrackingConfig {
142+
deprecated class OnAppendCookieSecureTrackingConfig extends OnAppendCookieTrackingConfig {
141143
OnAppendCookieSecureTrackingConfig() { this = "OnAppendCookieSecureTrackingConfig" }
142144

143145
override string propertyName() { result = "Secure" }
144146
}
145147

146148
/**
149+
* DEPRECATED: Use `OnAppendCookieHttpOnlyTracking` instead.
150+
*
147151
* Tracks if a callback used in `OnAppendCookie` sets `HttpOnly` to `true`.
148152
*/
149-
class OnAppendCookieHttpOnlyTrackingConfig extends OnAppendCookieTrackingConfig {
153+
deprecated class OnAppendCookieHttpOnlyTrackingConfig extends OnAppendCookieTrackingConfig {
150154
OnAppendCookieHttpOnlyTrackingConfig() { this = "OnAppendCookieHttpOnlyTrackingConfig" }
151155

152156
override string propertyName() { result = "HttpOnly" }
@@ -206,3 +210,83 @@ abstract private class OnAppendCookieTrackingConfig extends DataFlow::Configurat
206210
)
207211
}
208212
}
213+
214+
private signature string propertyName();
215+
216+
/**
217+
* Configuration for tracking if a callback used in `OnAppendCookie` sets a cookie property to `true`.
218+
*/
219+
private module OnAppendCookieTrackingConfig<propertyName/0 getPropertyName> implements
220+
DataFlow::ConfigSig
221+
{
222+
/**
223+
* Specifies the cookie property name to track.
224+
*/
225+
predicate isSource(DataFlow::Node source) {
226+
exists(PropertyWrite pw, Assignment delegateAssign, Callable c |
227+
pw.getProperty().getName() = "OnAppendCookie" and
228+
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreBuilderCookiePolicyOptions and
229+
delegateAssign.getLValue() = pw and
230+
(
231+
exists(LambdaExpr lambda |
232+
delegateAssign.getRValue() = lambda and
233+
lambda = c
234+
)
235+
or
236+
exists(DelegateCreation delegate |
237+
delegateAssign.getRValue() = delegate and
238+
delegate.getArgument().(CallableAccess).getTarget() = c
239+
)
240+
) and
241+
c.getParameter(0) = source.asParameter()
242+
)
243+
}
244+
245+
predicate isSink(DataFlow::Node sink) {
246+
exists(PropertyWrite pw, Assignment a |
247+
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
248+
pw.getProperty().getName() = getPropertyName() and
249+
a.getLValue() = pw and
250+
exists(Expr val |
251+
DataFlow::localExprFlow(val, a.getRValue()) and
252+
val.getValue() = "true"
253+
) and
254+
sink.asExpr() = pw.getQualifier()
255+
)
256+
}
257+
258+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
259+
node2.asExpr() =
260+
any(PropertyRead pr |
261+
pr.getQualifier() = node1.asExpr() and
262+
pr.getProperty().getDeclaringType() instanceof
263+
MicrosoftAspNetCoreCookiePolicyAppendCookieContext
264+
)
265+
}
266+
}
267+
268+
private string getPropertyNameSecure() { result = "Secure" }
269+
270+
/**
271+
* Configuration module for tracking if a callback used in `OnAppendCookie` sets `Secure` to `true`.
272+
*/
273+
private module OnAppendCookieSecureTrackingConfig =
274+
OnAppendCookieTrackingConfig<getPropertyNameSecure/0>;
275+
276+
/**
277+
* Tracks if a callback used in `OnAppendCookie` sets `Secure` to `true`.
278+
*/
279+
module OnAppendCookieSecureTracking = DataFlow::Global<OnAppendCookieSecureTrackingConfig>;
280+
281+
private string getPropertyNameHttpOnly() { result = "HttpOnly" }
282+
283+
/**
284+
* Configuration module for tracking if a callback used in `OnAppendCookie` sets `HttpOnly` to `true`.
285+
*/
286+
private module OnAppendCookieHttpOnlyTrackingConfig =
287+
OnAppendCookieTrackingConfig<getPropertyNameHttpOnly/0>;
288+
289+
/**
290+
* Tracks if a callback used in `OnAppendCookie` sets `HttpOnly` to `true`.
291+
*/
292+
module OnAppendCookieHttpOnlyTracking = DataFlow::Global<OnAppendCookieHttpOnlyTrackingConfig>;

0 commit comments

Comments
 (0)