Skip to content

Commit 031a79b

Browse files
edvraaowen-mc
authored andcommitted
Gorilla Store Save sink
1 parent 8110c3d commit 031a79b

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,16 @@ private class GorillaSessionSaveSink extends DataFlow::Node {
173173
}
174174
}
175175

176+
private class GorillaStoreSaveSink extends DataFlow::Node {
177+
GorillaStoreSaveSink() {
178+
exists(DataFlow::MethodCallNode mcn |
179+
this = mcn.getArgument(2) and
180+
mcn.getTarget()
181+
.hasQualifiedName(package("github.com/gorilla/sessions", ""), "CookieStore", "Save")
182+
)
183+
}
184+
}
185+
176186
/**
177187
* Tracks from gorilla cookie store creation to `gorilla/sessions.Session.Save`.
178188
*/
@@ -188,7 +198,10 @@ class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuratio
188198
.hasQualifiedName(package("github.com/gorilla/sessions", ""), "NewCookieStore")
189199
}
190200

191-
override predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink }
201+
override predicate isSink(DataFlow::Node sink) {
202+
sink instanceof GorillaSessionSaveSink or
203+
sink instanceof GorillaStoreSaveSink
204+
}
192205

193206
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
194207
exists(DataFlow::MethodCallNode cn |

ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ edges
7676
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:146:16:146:20 | store : pointer type |
7777
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:158:16:158:20 | store : pointer type |
7878
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:170:16:170:20 | store : pointer type |
79+
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:183:16:183:20 | store : pointer type |
80+
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:195:16:195:20 | store : pointer type |
7981
| CookieWithoutHttpOnly.go:126:16:126:20 | store : pointer type | CookieWithoutHttpOnly.go:129:2:129:8 | session |
8082
| CookieWithoutHttpOnly.go:133:14:133:18 | false : bool | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session |
8183
| CookieWithoutHttpOnly.go:133:14:133:18 | false : bool | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session |
@@ -156,6 +158,8 @@ edges
156158
| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal : Options | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session |
157159
| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal : Options | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session |
158160
| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal : Options | CookieWithoutHttpOnly.go:178:2:178:8 | session |
161+
| CookieWithoutHttpOnly.go:183:16:183:20 | store : pointer type | CookieWithoutHttpOnly.go:191:19:191:25 | session |
162+
| CookieWithoutHttpOnly.go:195:16:195:20 | store : pointer type | CookieWithoutHttpOnly.go:202:19:202:25 | session |
159163
nodes
160164
| CookieWithoutHttpOnly.go:11:7:14:2 | struct literal : Cookie | semmle.label | struct literal : Cookie |
161165
| CookieWithoutHttpOnly.go:15:20:15:21 | &... | semmle.label | &... |
@@ -257,7 +261,11 @@ nodes
257261
| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal : Options | semmle.label | struct literal : Options |
258262
| CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session |
259263
| CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session |
260-
| CookieWithoutHttpOnly.go:190:66:190:70 | false | semmle.label | false |
264+
| CookieWithoutHttpOnly.go:183:16:183:20 | store : pointer type | semmle.label | store : pointer type |
265+
| CookieWithoutHttpOnly.go:191:19:191:25 | session | semmle.label | session |
266+
| CookieWithoutHttpOnly.go:195:16:195:20 | store : pointer type | semmle.label | store : pointer type |
267+
| CookieWithoutHttpOnly.go:202:19:202:25 | session | semmle.label | session |
268+
| CookieWithoutHttpOnly.go:214:66:214:70 | false | semmle.label | false |
261269
#select
262270
| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal : Cookie | CookieWithoutHttpOnly.go:15:20:15:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
263271
| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:22:13:22:17 | false : bool | CookieWithoutHttpOnly.go:24:20:24:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
@@ -269,4 +277,6 @@ nodes
269277
| CookieWithoutHttpOnly.go:129:2:129:8 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:129:2:129:8 | session | Cookie attribute 'HttpOnly' is not set to true. |
270278
| CookieWithoutHttpOnly.go:142:2:142:8 | session | CookieWithoutHttpOnly.go:133:14:133:18 | false : bool | CookieWithoutHttpOnly.go:142:2:142:8 | session | Cookie attribute 'HttpOnly' is not set to true. |
271279
| CookieWithoutHttpOnly.go:153:2:153:8 | session | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal : Options | CookieWithoutHttpOnly.go:153:2:153:8 | session | Cookie attribute 'HttpOnly' is not set to true. |
272-
| CookieWithoutHttpOnly.go:190:66:190:70 | false | CookieWithoutHttpOnly.go:190:66:190:70 | false | CookieWithoutHttpOnly.go:190:66:190:70 | false | Cookie attribute 'HttpOnly' is not set to true. |
280+
| CookieWithoutHttpOnly.go:191:19:191:25 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:191:19:191:25 | session | Cookie attribute 'HttpOnly' is not set to true. |
281+
| CookieWithoutHttpOnly.go:202:19:202:25 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:202:19:202:25 | session | Cookie attribute 'HttpOnly' is not set to true. |
282+
| CookieWithoutHttpOnly.go:214:66:214:70 | false | CookieWithoutHttpOnly.go:214:66:214:70 | false | CookieWithoutHttpOnly.go:214:66:214:70 | false | Cookie attribute 'HttpOnly' is not set to true. |

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,30 @@ func handler17(w http.ResponseWriter, r *http.Request, httpOnly bool) {
178178
session.Save(r, w) // GOOD: value is unknown
179179
}
180180

181+
func handler18(w http.ResponseWriter, r *http.Request) {
182+
httpOnly := false
183+
session, _ := store.Get(r, "session-name")
184+
session.Values["foo"] = "secret"
185+
186+
session.Options = &sessions.Options{
187+
MaxAge: -1,
188+
HttpOnly: httpOnly,
189+
}
190+
191+
store.Save(r, w, session) // BAD: Explicitly set to false
192+
}
193+
194+
func handler19(w http.ResponseWriter, r *http.Request) {
195+
session, _ := store.Get(r, "session-name")
196+
session.Values["foo"] = "secret"
197+
198+
session.Options = &sessions.Options{
199+
MaxAge: -1,
200+
}
201+
202+
store.Save(r, w, session) // BAD: default (false) is used
203+
}
204+
181205
func main() {
182206

183207
router := gin.Default()

0 commit comments

Comments
 (0)