Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 00cc78d

Browse files
committed
Make CookieWithoutHttpOnly use new API
The extra nodes in .expected files are due to the changes from #13717, which are not applied to configuration classes extending DataFlow::Configuration or TaintTracking::Configuration.
1 parent a7382e0 commit 00cc78d

3 files changed

Lines changed: 414 additions & 208 deletions

File tree

go/ql/src/experimental/CWE-1004/AuthCookie.qll

Lines changed: 146 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ private class SetCookieSink extends DataFlow::Node {
6565
}
6666

6767
/**
68+
* DEPRECATED: Use `NameToNetHttpCookieTrackingFlow` instead.
69+
*
6870
* A taint-tracking configuration for tracking flow from sensitive names to
6971
* `net/http.SetCookie`.
7072
*/
71-
class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration {
73+
deprecated class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration {
7274
NameToNetHttpCookieTrackingConfiguration() { this = "NameToNetHttpCookieTrackingConfiguration" }
7375

7476
override predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) }
@@ -84,11 +86,29 @@ class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configurat
8486
}
8587
}
8688

89+
private module NameToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig {
90+
predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) }
91+
92+
predicate isSink(DataFlow::Node sink) { sink instanceof SetCookieSink }
93+
94+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
95+
exists(StructLit sl |
96+
sl.getType() instanceof NetHttpCookieType and
97+
getValueForFieldWrite(sl, "Name") = pred and
98+
sl = succ.asExpr()
99+
)
100+
}
101+
}
102+
103+
module NameToNetHttpCookieTrackingFlow = TaintTracking::Global<NameToNetHttpCookieTrackingConfig>;
104+
87105
/**
106+
* DEPRECATED: Use `BoolToNetHttpCookieTrackingFlow` instead.
107+
*
88108
* A taint-tracking configuration for tracking flow from `bool` assigned to
89109
* `HttpOnly` that flows into `net/http.SetCookie`.
90110
*/
91-
class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration {
111+
deprecated class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration {
92112
BoolToNetHttpCookieTrackingConfiguration() { this = "BoolToNetHttpCookieTrackingConfiguration" }
93113

94114
override predicate isSource(DataFlow::Node source) {
@@ -106,11 +126,31 @@ class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configurat
106126
}
107127
}
108128

129+
private module BoolToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig {
130+
predicate isSource(DataFlow::Node source) {
131+
source.getType().getUnderlyingType() instanceof BoolType
132+
}
133+
134+
predicate isSink(DataFlow::Node sink) { sink instanceof SetCookieSink }
135+
136+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
137+
exists(StructLit sl |
138+
sl.getType() instanceof NetHttpCookieType and
139+
getValueForFieldWrite(sl, "HttpOnly") = pred and
140+
sl = succ.asExpr()
141+
)
142+
}
143+
}
144+
145+
module BoolToNetHttpCookieTrackingFlow = TaintTracking::Global<BoolToNetHttpCookieTrackingConfig>;
146+
109147
/**
148+
* DEPRECATED: Use `BoolToGinSetCookieTrackingFlow` instead.
149+
*
110150
* A taint-tracking configuration for tracking flow from `HttpOnly` set to
111151
* `false` to `gin-gonic/gin.Context.SetCookie`.
112152
*/
113-
class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration {
153+
deprecated class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration {
114154
BoolToGinSetCookieTrackingConfiguration() { this = "BoolToGinSetCookieTrackingConfiguration" }
115155

116156
override predicate isSource(DataFlow::Node source) { source.getBoolValue() = false }
@@ -119,31 +159,48 @@ class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration {
119159
exists(DataFlow::MethodCallNode mcn |
120160
mcn.getTarget() instanceof GinContextSetCookieMethod and
121161
mcn.getArgument(6) = sink and
122-
exists(NameToGinSetCookieTrackingConfiguration cfg, DataFlow::Node nameArg |
123-
cfg.hasFlowTo(nameArg) and
162+
exists(DataFlow::Node nameArg |
163+
NameToGinSetCookieTrackingFlow::flowTo(nameArg) and
164+
mcn.getArgument(0) = nameArg
165+
)
166+
)
167+
}
168+
}
169+
170+
private module BoolToGinSetCookieTrackingConfig implements DataFlow::ConfigSig {
171+
predicate isSource(DataFlow::Node source) { source.getBoolValue() = false }
172+
173+
predicate isSink(DataFlow::Node sink) {
174+
exists(DataFlow::MethodCallNode mcn |
175+
mcn.getTarget() instanceof GinContextSetCookieMethod and
176+
mcn.getArgument(6) = sink and
177+
exists(DataFlow::Node nameArg |
178+
NameToGinSetCookieTrackingFlow::flowTo(nameArg) and
124179
mcn.getArgument(0) = nameArg
125180
)
126181
)
127182
}
128183
}
129184

185+
module BoolToGinSetCookieTrackingFlow = DataFlow::Global<BoolToGinSetCookieTrackingConfig>;
186+
130187
/**
131188
* A taint-tracking configuration for tracking flow from sensitive names to
132189
* `gin-gonic/gin.Context.SetCookie`.
133190
*/
134-
private class NameToGinSetCookieTrackingConfiguration extends DataFlow2::Configuration {
135-
NameToGinSetCookieTrackingConfiguration() { this = "NameToGinSetCookieTrackingConfiguration" }
136-
137-
override predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) }
191+
private module NameToGinSetCookieTrackingConfig implements DataFlow::ConfigSig {
192+
predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) }
138193

139-
override predicate isSink(DataFlow::Node sink) {
194+
predicate isSink(DataFlow::Node sink) {
140195
exists(DataFlow::MethodCallNode mcn |
141196
mcn.getTarget() instanceof GinContextSetCookieMethod and
142197
mcn.getArgument(0) = sink
143198
)
144199
}
145200
}
146201

202+
private module NameToGinSetCookieTrackingFlow = DataFlow::Global<NameToGinSetCookieTrackingConfig>;
203+
147204
/**
148205
* The receiver of `gorilla/sessions.Session.Save` call.
149206
*/
@@ -168,10 +225,12 @@ private class GorillaStoreSaveSink extends DataFlow::Node {
168225
}
169226

170227
/**
228+
* DEPRECATED: Use `GorillaCookieStoreSaveTrackingFlow` instead.
229+
*
171230
* A taint-tracking configuration for tracking flow from gorilla cookie store
172231
* creation to `gorilla/sessions.Session.Save`.
173232
*/
174-
class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuration {
233+
deprecated class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuration {
175234
GorillaCookieStoreSaveTrackingConfiguration() {
176235
this = "GorillaCookieStoreSaveTrackingConfiguration"
177236
}
@@ -198,11 +257,38 @@ class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuratio
198257
}
199258
}
200259

260+
private module GorillaCookieStoreSaveTrackingConfig implements DataFlow::ConfigSig {
261+
predicate isSource(DataFlow::Node source) {
262+
source
263+
.(DataFlow::CallNode)
264+
.getTarget()
265+
.hasQualifiedName(package("github.com/gorilla/sessions", ""), "NewCookieStore")
266+
}
267+
268+
predicate isSink(DataFlow::Node sink) {
269+
sink instanceof GorillaSessionSaveSink or
270+
sink instanceof GorillaStoreSaveSink
271+
}
272+
273+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
274+
exists(DataFlow::MethodCallNode cn |
275+
cn.getTarget()
276+
.hasQualifiedName(package("github.com/gorilla/sessions", ""), "CookieStore", "Get") and
277+
pred = cn.getReceiver() and
278+
succ = cn.getResult(0)
279+
)
280+
}
281+
}
282+
283+
module GorillaCookieStoreSaveTrackingFlow = DataFlow::Global<GorillaCookieStoreSaveTrackingConfig>;
284+
201285
/**
286+
* DEPRECATED: Use `GorillaSessionOptionsTrackingFlow` instead.
287+
*
202288
* A taint-tracking configuration for tracking flow from session options to
203289
* `gorilla/sessions.Session.Save`.
204290
*/
205-
class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration {
291+
deprecated class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration {
206292
GorillaSessionOptionsTrackingConfiguration() {
207293
this = "GorillaSessionOptionsTrackingConfiguration"
208294
}
@@ -224,11 +310,35 @@ class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configur
224310
}
225311
}
226312

313+
private module GorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSig {
314+
predicate isSource(DataFlow::Node source) {
315+
exists(StructLit sl |
316+
sl.getType().hasQualifiedName(package("github.com/gorilla/sessions", ""), "Options") and
317+
source.asExpr() = sl
318+
)
319+
}
320+
321+
predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink }
322+
323+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
324+
exists(GorillaSessionOptionsField f, DataFlow::Write w, DataFlow::Node base |
325+
w.writesField(base, f, pred) and
326+
succ = base
327+
)
328+
}
329+
}
330+
331+
module GorillaSessionOptionsTrackingFlow =
332+
TaintTracking::Global<GorillaSessionOptionsTrackingConfig>;
333+
227334
/**
335+
* DEPRECATED: Use `BoolToGorillaSessionOptionsTrackingFlow` instead.
336+
*
228337
* A taint-tracking configuration for tracking flow from a `bool` assigned to
229338
* `HttpOnly` to `gorilla/sessions.Session.Save`.
230339
*/
231-
class BoolToGorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration {
340+
deprecated class BoolToGorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration
341+
{
232342
BoolToGorillaSessionOptionsTrackingConfiguration() {
233343
this = "BoolToGorillaSessionOptionsTrackingConfiguration"
234344
}
@@ -251,3 +361,26 @@ class BoolToGorillaSessionOptionsTrackingConfiguration extends TaintTracking::Co
251361
)
252362
}
253363
}
364+
365+
private module BoolToGorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSig {
366+
predicate isSource(DataFlow::Node source) {
367+
source.getType().getUnderlyingType() instanceof BoolType
368+
}
369+
370+
predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink }
371+
372+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
373+
exists(StructLit sl |
374+
getValueForFieldWrite(sl, "HttpOnly") = pred and
375+
sl = succ.asExpr()
376+
)
377+
or
378+
exists(GorillaSessionOptionsField f, DataFlow::Write w, DataFlow::Node base |
379+
w.writesField(base, f, pred) and
380+
succ = base
381+
)
382+
}
383+
}
384+
385+
module BoolToGorillaSessionOptionsTrackingFlow =
386+
TaintTracking::Global<BoolToGorillaSessionOptionsTrackingConfig>;

go/ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,40 @@
1515

1616
import go
1717
import AuthCookie
18-
import DataFlow::PathGraph
18+
19+
module MergedFlow1 =
20+
DataFlow::MergePathGraph<NameToNetHttpCookieTrackingFlow::PathNode,
21+
BoolToNetHttpCookieTrackingFlow::PathNode, NameToNetHttpCookieTrackingFlow::PathGraph,
22+
BoolToNetHttpCookieTrackingFlow::PathGraph>;
23+
24+
module MergedFlow2 =
25+
DataFlow::MergePathGraph3<GorillaCookieStoreSaveTrackingFlow::PathNode,
26+
GorillaSessionOptionsTrackingFlow::PathNode, BoolToGorillaSessionOptionsTrackingFlow::PathNode,
27+
GorillaCookieStoreSaveTrackingFlow::PathGraph, GorillaSessionOptionsTrackingFlow::PathGraph,
28+
BoolToGorillaSessionOptionsTrackingFlow::PathGraph>;
29+
30+
module MergedFlow =
31+
DataFlow::MergePathGraph3<MergedFlow1::PathNode, BoolToGinSetCookieTrackingFlow::PathNode,
32+
MergedFlow2::PathNode, MergedFlow1::PathGraph, BoolToGinSetCookieTrackingFlow::PathGraph,
33+
MergedFlow2::PathGraph>;
34+
35+
import MergedFlow::PathGraph
1936

2037
/** Holds if `HttpOnly` of `net/http.SetCookie` is set to `false` or not set (default value is used). */
21-
predicate isNetHttpCookieFlow(DataFlow::PathNode source, DataFlow::PathNode sink) {
22-
exists(DataFlow::PathNode sensitiveName, DataFlow::PathNode setCookieSink |
23-
exists(NameToNetHttpCookieTrackingConfiguration cfg |
24-
cfg.hasFlowPath(sensitiveName, setCookieSink)
25-
) and
38+
predicate isNetHttpCookieFlow(MergedFlow1::PathNode source, MergedFlow1::PathNode sink) {
39+
exists(
40+
NameToNetHttpCookieTrackingFlow::PathNode sensitiveName,
41+
NameToNetHttpCookieTrackingFlow::PathNode setCookieSink
42+
|
43+
NameToNetHttpCookieTrackingFlow::flowPath(sensitiveName, setCookieSink) and
2644
(
27-
not any(BoolToNetHttpCookieTrackingConfiguration cfg).hasFlowTo(setCookieSink.getNode()) and
28-
source = sensitiveName and
29-
sink = setCookieSink
45+
not BoolToNetHttpCookieTrackingFlow::flowTo(sink.getNode()) and
46+
source.asPathNode1() = sensitiveName and
47+
sink.asPathNode1() = setCookieSink
3048
or
31-
exists(BoolToNetHttpCookieTrackingConfiguration cfg, DataFlow::PathNode setCookieSink2 |
32-
cfg.hasFlowPath(source, setCookieSink2) and
33-
source.getNode().getBoolValue() = false and
34-
sink = setCookieSink2 and
35-
setCookieSink.getNode() = setCookieSink2.getNode()
36-
)
49+
BoolToNetHttpCookieTrackingFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) and
50+
source.getNode().getBoolValue() = false and
51+
setCookieSink.getNode() = sink.getNode()
3752
)
3853
)
3954
}
@@ -42,44 +57,38 @@ predicate isNetHttpCookieFlow(DataFlow::PathNode source, DataFlow::PathNode sink
4257
* Holds if there is gorilla cookie store creation to `Save` path and
4358
* `HttpOnly` is set to `false` or not set (default value is used).
4459
*/
45-
predicate isGorillaSessionsCookieFlow(DataFlow::PathNode source, DataFlow::PathNode sink) {
46-
exists(DataFlow::PathNode cookieStoreCreate, DataFlow::PathNode sessionSave |
47-
any(GorillaCookieStoreSaveTrackingConfiguration cfg).hasFlowPath(cookieStoreCreate, sessionSave) and
60+
predicate isGorillaSessionsCookieFlow(MergedFlow2::PathNode source, MergedFlow2::PathNode sink) {
61+
exists(
62+
GorillaCookieStoreSaveTrackingFlow::PathNode cookieStoreCreate,
63+
GorillaCookieStoreSaveTrackingFlow::PathNode sessionSave
64+
|
65+
GorillaCookieStoreSaveTrackingFlow::flowPath(cookieStoreCreate, sessionSave) and
4866
(
49-
not any(GorillaSessionOptionsTrackingConfiguration cfg).hasFlowTo(sessionSave.getNode()) and
50-
source = cookieStoreCreate and
51-
sink = sessionSave
67+
not GorillaSessionOptionsTrackingFlow::flowTo(sink.getNode()) and
68+
source.asPathNode1() = cookieStoreCreate and
69+
sink.asPathNode1() = sessionSave
5270
or
53-
exists(
54-
GorillaSessionOptionsTrackingConfiguration cfg, DataFlow::PathNode options,
55-
DataFlow::PathNode sessionSave2
56-
|
57-
cfg.hasFlowPath(options, sessionSave2) and
71+
exists(MergedFlow2::PathNode options, MergedFlow2::PathNode sessionSave2 |
72+
GorillaSessionOptionsTrackingFlow::flowPath(options.asPathNode2(),
73+
sessionSave2.asPathNode2()) and
5874
(
59-
not any(BoolToGorillaSessionOptionsTrackingConfiguration boolCfg)
60-
.hasFlowTo(sessionSave.getNode()) and
61-
sink = sessionSave2 and
75+
not BoolToGorillaSessionOptionsTrackingFlow::flowTo(sink.getNode()) and
6276
source = options and
77+
sink = sessionSave2 and
6378
sessionSave.getNode() = sessionSave2.getNode()
6479
or
65-
exists(
66-
BoolToGorillaSessionOptionsTrackingConfiguration boolCfg,
67-
DataFlow::PathNode sessionSave3
68-
|
69-
boolCfg.hasFlowPath(source, sessionSave3) and
70-
source.getNode().getBoolValue() = false and
71-
sink = sessionSave3 and
72-
sessionSave.getNode() = sessionSave3.getNode()
73-
)
80+
BoolToGorillaSessionOptionsTrackingFlow::flowPath(source.asPathNode3(), sink.asPathNode3()) and
81+
source.getNode().getBoolValue() = false and
82+
sink.getNode() = sessionSave.getNode()
7483
)
7584
)
7685
)
7786
)
7887
}
7988

80-
from DataFlow::PathNode source, DataFlow::PathNode sink
89+
from MergedFlow::PathNode source, MergedFlow::PathNode sink
8190
where
82-
isNetHttpCookieFlow(source, sink) or
83-
any(BoolToGinSetCookieTrackingConfiguration cfg).hasFlowPath(source, sink) or
84-
isGorillaSessionsCookieFlow(source, sink)
91+
isNetHttpCookieFlow(source.asPathNode1(), sink.asPathNode1()) or
92+
BoolToGinSetCookieTrackingFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) or
93+
isGorillaSessionsCookieFlow(source.asPathNode3(), sink.asPathNode3())
8594
select sink.getNode(), source, sink, "Cookie attribute 'HttpOnly' is not set to true."

0 commit comments

Comments
 (0)