Skip to content

Commit 72f2851

Browse files
committed
Move test check to the sink
1 parent 48975fa commit 72f2851

File tree

1 file changed

+19
-25
lines changed

1 file changed

+19
-25
lines changed

java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -73,34 +73,29 @@ class CookieResponseSink extends DataFlow::ExprNode {
7373
ma instanceof SetCookieMethodAccess and
7474
this.getExpr() = ma.getArgument(1) and
7575
not hasHttpOnlyExpr(this.getExpr()) // response.addHeader("Set-Cookie", "token=" +authId + ";HttpOnly;Secure")
76-
)
76+
) and
77+
not isTestMethod(ma) // Test class or method
7778
)
7879
}
7980
}
8081

81-
/** A JAX-RS `NewCookie` constructor that sets `HttpOnly` to true. */
82-
class HttpOnlyNewCookie extends ClassInstanceExpr {
83-
HttpOnlyNewCookie() {
84-
this.getConstructedType()
85-
.hasQualifiedName(["javax.ws.rs.core", "jakarta.ws.rs.core"], "NewCookie") and
86-
(
87-
this.getNumArgument() = 6 and this.getArgument(5).(BooleanLiteral).getBooleanValue() = true // NewCookie(Cookie cookie, String comment, int maxAge, Date expiry, boolean secure, boolean httpOnly)
88-
or
89-
this.getNumArgument() = 8 and
90-
this.getArgument(6).getType() instanceof BooleanType and
91-
this.getArgument(7).(BooleanLiteral).getBooleanValue() = true // NewCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly)
92-
or
93-
this.getNumArgument() = 10 and this.getArgument(9).(BooleanLiteral).getBooleanValue() = true // NewCookie(String name, String value, String path, String domain, int version, String comment, int maxAge, Date expiry, boolean secure, boolean httpOnly)
94-
)
95-
}
82+
/** Holds if `cie` is an invocation of a JAX-RS `NewCookie` constructor that sets `HttpOnly` to true. */
83+
predicate setHttpOnlyInNewCookie(ClassInstanceExpr cie) {
84+
cie.getConstructedType().hasQualifiedName(["javax.ws.rs.core", "jakarta.ws.rs.core"], "NewCookie") and
85+
(
86+
cie.getNumArgument() = 6 and cie.getArgument(5).(BooleanLiteral).getBooleanValue() = true // NewCookie(Cookie cookie, String comment, int maxAge, Date expiry, boolean secure, boolean httpOnly)
87+
or
88+
cie.getNumArgument() = 8 and
89+
cie.getArgument(6).getType() instanceof BooleanType and
90+
cie.getArgument(7).(BooleanLiteral).getBooleanValue() = true // NewCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly)
91+
or
92+
cie.getNumArgument() = 10 and cie.getArgument(9).(BooleanLiteral).getBooleanValue() = true // NewCookie(String name, String value, String path, String domain, int version, String comment, int maxAge, Date expiry, boolean secure, boolean httpOnly)
93+
)
9694
}
9795

9896
/** The cookie constructor. */
9997
class CookieTaintPreservingConstructor extends Constructor, TaintPreservingCallable {
100-
CookieTaintPreservingConstructor() {
101-
this.getDeclaringType() instanceof CookieClass and
102-
not exists(HttpOnlyNewCookie hie | hie.getConstructor() = this)
103-
}
98+
CookieTaintPreservingConstructor() { this.getDeclaringType() instanceof CookieClass }
10499

105100
override predicate returnsTaintFrom(int arg) { arg = 0 }
106101
}
@@ -122,9 +117,8 @@ class CookieInstanceExpr extends TaintPreservingCallable {
122117
* c) in a test class whose name has the word `test`
123118
* d) in a test class implementing a test framework such as JUnit or TestNG
124119
*/
125-
predicate isTestMethod(DataFlow::Node node) {
126-
exists(MethodAccess ma, Method m |
127-
node.asExpr() = ma.getAnArgument() and
120+
predicate isTestMethod(MethodAccess ma) {
121+
exists(Method m |
128122
m = ma.getEnclosingCallable() and
129123
(
130124
m.getDeclaringType().getName().toLowerCase().matches("%test%") or // Simple check to exclude test classes to reduce FPs
@@ -149,8 +143,8 @@ class MissingHttpOnlyConfiguration extends TaintTracking::Configuration {
149143
override predicate isSink(DataFlow::Node sink) { sink instanceof CookieResponseSink }
150144

151145
override predicate isSanitizer(DataFlow::Node node) {
152-
// Test class or method
153-
isTestMethod(node)
146+
// new NewCookie("session-access-key", accessKey, "/", null, null, 0, true, true)
147+
setHttpOnlyInNewCookie(node.asExpr())
154148
}
155149
}
156150

0 commit comments

Comments
 (0)