Skip to content

Commit 779768d

Browse files
Fixes, add secure query
1 parent 9eef624 commit 779768d

File tree

3 files changed

+69
-23
lines changed

3 files changed

+69
-23
lines changed

go/ql/lib/semmle/go/security/SecureCookies.qll

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ private module SensitiveCookieNameConfig implements DataFlow::ConfigSig {
2727
}
2828

2929
/** Tracks flow from sensitive names to HTTP cookie writes. */
30-
module SensitiveCookieNameFlow = DataFlow::Global<SensitiveCookieNameConfig>;
30+
module SensitiveCookieNameFlow = TaintTracking::Global<SensitiveCookieNameConfig>;
3131

3232
private module BooleanCookieSecureConfig implements DataFlow::ConfigSig {
33-
predicate isSource(DataFlow::Node source) { exists(source.asExpr().getBoolValue()) }
33+
predicate isSource(DataFlow::Node source) {
34+
source.getType().getUnderlyingType() instanceof BoolType
35+
}
3436

3537
predicate isSink(DataFlow::Node sink) { exists(Http::CookieWrite cw | sink = cw.getSecure()) }
3638

@@ -39,11 +41,13 @@ private module BooleanCookieSecureConfig implements DataFlow::ConfigSig {
3941
}
4042
}
4143

42-
/** Tracks flow from boolean expressions to the `Secure` attribute HTTP cookie writes. */
43-
module BooleanCookieSecureFlow = DataFlow::Global<BooleanCookieSecureConfig>;
44+
/** Tracks flow from boolean expressions to the `Secure` attribute of HTTP cookie writes. */
45+
module BooleanCookieSecureFlow = TaintTracking::Global<BooleanCookieSecureConfig>;
4446

4547
private module BooleanCookieHttpOnlyConfig implements DataFlow::ConfigSig {
46-
predicate isSource(DataFlow::Node source) { exists(source.asExpr().getBoolValue()) }
48+
predicate isSource(DataFlow::Node source) {
49+
source.getType().getUnderlyingType() instanceof BoolType
50+
}
4751

4852
predicate isSink(DataFlow::Node sink) { exists(Http::CookieWrite cw | sink = cw.getHttpOnly()) }
4953

@@ -52,28 +56,53 @@ private module BooleanCookieHttpOnlyConfig implements DataFlow::ConfigSig {
5256
}
5357
}
5458

55-
/** Tracks flow from boolean expressions to the `HttpOnly` attribute HTTP cookie writes. */
56-
module BooleanCookieHttpOnlyFlow = DataFlow::Global<BooleanCookieHttpOnlyConfig>;
59+
/** Tracks flow from boolean expressions to the `HttpOnly` attribute of HTTP cookie writes. */
60+
module BooleanCookieHttpOnlyFlow = TaintTracking::Global<BooleanCookieHttpOnlyConfig>;
5761

62+
/** Holds if `cw` has the `Secure` attribute left at its default value of `false`. */
5863
predicate isInsecureDefault(Http::CookieWrite cw) {
5964
not BooleanCookieSecureFlow::flow(_, cw.getSecure())
6065
}
6166

62-
predicate isNonHttpOnlyDefault(Http::CookieWrite cw) {
63-
not BooleanCookieHttpOnlyFlow::flow(_, cw.getHttpOnly())
64-
}
65-
67+
/** Holds if `cw` has the `Secure` attribute explicitly set to `false`, from the expression `boolFalse`. */
6668
predicate isInsecureDirect(Http::CookieWrite cw, Expr boolFalse) {
6769
BooleanCookieSecureFlow::flow(DataFlow::exprNode(boolFalse), cw.getSecure()) and
6870
boolFalse.getBoolValue() = false
6971
}
7072

73+
/** Holds if `cw` has the `Secure` attribute set to `false`, either explicitly or by default. */
74+
predicate isInsecureCookie(Http::CookieWrite cw) {
75+
isInsecureDefault(cw) or
76+
isInsecureDirect(cw, _)
77+
}
78+
79+
/** Holds if `cw` has the `HttpOnly` attribute left at its default value of `false`. */
80+
predicate isNonHttpOnlyDefault(Http::CookieWrite cw) {
81+
not BooleanCookieHttpOnlyFlow::flow(_, cw.getHttpOnly())
82+
}
83+
84+
/** Holds if `cw` has the `HttpOnly` attribute explicitly set to `false`, from the expression `boolFalse`. */
7185
predicate isNonHttpOnlyDirect(Http::CookieWrite cw, Expr boolFalse) {
7286
BooleanCookieHttpOnlyFlow::flow(DataFlow::exprNode(boolFalse), cw.getHttpOnly()) and
7387
boolFalse.getBoolValue() = false
7488
}
7589

76-
predicate isSensitiveCookie(Http::CookieWrite cw, Expr nameExpr, string name) {
77-
SensitiveCookieNameFlow::flow(DataFlow::exprNode(nameExpr), cw.getName()) and
90+
/** Holds if `cw` has the `HttpOnly` attribute set to `false`, either explicitly or by default. */
91+
predicate isNonHttpOnlyCookie(Http::CookieWrite cw) {
92+
isNonHttpOnlyDefault(cw) or
93+
isNonHttpOnlyDirect(cw, _)
94+
}
95+
96+
/**
97+
* Holds if `cw` has the sensitive name `name`, from the expression `nameExpr`.
98+
* `source` and `sink` represent the data flow path from the sensitive name expression to the cookie write.
99+
*/
100+
predicate isSensitiveCookie(
101+
Http::CookieWrite cw, Expr nameExpr, string name, SensitiveCookieNameFlow::PathNode source,
102+
SensitiveCookieNameFlow::PathNode sink
103+
) {
104+
SensitiveCookieNameFlow::flowPath(source, sink) and
105+
source.getNode().asExpr() = nameExpr and
106+
sink.getNode() = cw.getName() and
78107
isSensitiveExpr(nameExpr, name)
79108
}

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,24 @@
44
* malicious JavaScript to steal it in case of XSS vulnerability. Always set
55
* 'HttpOnly' to 'true' to authentication related cookie to make it
66
* not accessible by JavaScript.
7-
* @kind problem
7+
* @kind path-problem
88
* @problem.severity warning
99
* @precision high
1010
* @id go/cookie-httponly-not-set
1111
* @tags security
12-
* experimental
1312
* external/cwe/cwe-1004
1413
*/
1514

1615
import go
1716
import semmle.go.security.SecureCookies
1817
import semmle.go.concepts.HTTP
18+
import SensitiveCookieNameFlow::PathGraph
1919

20-
from Http::CookieWrite cw, Expr sensitiveNameExpr, string name
20+
from
21+
Http::CookieWrite cw, Expr sensitiveNameExpr, string name,
22+
SensitiveCookieNameFlow::PathNode source, SensitiveCookieNameFlow::PathNode sink
2123
where
22-
isSensitiveCookie(cw, sensitiveNameExpr, name) and
23-
(
24-
isNonHttpOnlyDefault(cw)
25-
or
26-
isNonHttpOnlyDirect(cw, _)
27-
)
28-
select cw, "Sensitive cookie $@ does not set HttpOnly to true", sensitiveNameExpr, name
24+
isSensitiveCookie(cw, sensitiveNameExpr, name, source, sink) and
25+
isNonHttpOnlyCookie(cw)
26+
select cw, source, sink, "Sensitive cookie $@ does not set HttpOnly attribute to true.",
27+
sensitiveNameExpr, name
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* @name 'Secure' attribute is not set to true
3+
* @description todo
4+
* @kind problem
5+
* @problem.severity warning
6+
* @precision high
7+
* @id go/cookie-secure-not-set
8+
* @tags security
9+
* external/cwe/cwe-1004
10+
*/
11+
12+
import go
13+
import semmle.go.security.SecureCookies
14+
import semmle.go.concepts.HTTP
15+
16+
from Http::CookieWrite cw
17+
where isInsecureCookie(cw)
18+
select cw, "Cookie does not set Secure attribute to true"

0 commit comments

Comments
 (0)