Skip to content

Commit c17ef42

Browse files
committed
Insecure cookie query: accept ServletRequest.isSecure(), and allow more than one possible input to a setSecure(...) call.
1 parent 1af0e9b commit c17ef42

File tree

3 files changed

+87
-7
lines changed

3 files changed

+87
-7
lines changed

java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,31 @@
1313

1414
import java
1515
import semmle.code.java.frameworks.Servlets
16+
import semmle.code.java.dataflow.DataFlow
17+
18+
predicate isSafeSecureCookieSetting(Expr e) {
19+
e.(CompileTimeConstantExpr).getBooleanValue() = true
20+
or
21+
exists(Method isSecure |
22+
isSecure.getName() = "isSecure" and
23+
isSecure.getDeclaringType().getASourceSupertype*() instanceof ServletRequest
24+
|
25+
e.(MethodAccess).getMethod() = isSecure
26+
)
27+
}
1628

1729
from MethodAccess add
1830
where
1931
add.getMethod() instanceof ResponseAddCookieMethod and
2032
not exists(Variable cookie, MethodAccess m |
2133
add.getArgument(0) = cookie.getAnAccess() and
2234
m.getMethod().getName() = "setSecure" and
23-
m.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true and
35+
forex(DataFlow::Node argSource |
36+
DataFlow::localFlow(argSource, DataFlow::exprNode(m.getArgument(0))) and
37+
not DataFlow::localFlowStep(_, argSource)
38+
|
39+
isSafeSecureCookieSetting(argSource.asExpr())
40+
) and
2441
m.getQualifier() = cookie.getAnAccess()
2542
)
2643
select add, "Cookie is added to response without the 'secure' flag being set."
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
| Test.java:16:4:16:29 | addCookie(...) | Cookie is added to response without the 'secure' flag being set. |
1+
| Test.java:19:4:19:29 | addCookie(...) | Cookie is added to response without the 'secure' flag being set. |
2+
| Test.java:28:4:28:29 | addCookie(...) | Cookie is added to response without the 'secure' flag being set. |
3+
| Test.java:37:4:37:29 | addCookie(...) | Cookie is added to response without the 'secure' flag being set. |
4+
| Test.java:51:4:51:29 | addCookie(...) | Cookie is added to response without the 'secure' flag being set. |

java/ql/test/query-tests/security/CWE-311/CWE-614/semmle/tests/Test.java

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,81 @@
88
import javax.servlet.http.*;
99

1010
class Test {
11-
public static void test(HttpServletRequest request, HttpServletResponse response) {
11+
12+
public static final boolean constTrue = true;
13+
14+
public static void test(HttpServletRequest request, HttpServletResponse response, boolean alwaysSecure, boolean otherInput) {
1215
{
1316
Cookie cookie = new Cookie("secret" ,"fakesecret");
14-
17+
1518
// BAD: secure flag not set
1619
response.addCookie(cookie);
17-
20+
1821
}
19-
22+
2023
{
2124
Cookie cookie = new Cookie("secret" ,"fakesecret");
22-
25+
26+
// BAD: secure flag set to false
27+
cookie.setSecure(false);
28+
response.addCookie(cookie);
29+
30+
}
31+
32+
{
33+
Cookie cookie = new Cookie("secret" ,"fakesecret");
34+
35+
// BAD: secure flag set to something not clearly true or request.isSecure()
36+
cookie.setSecure(otherInput);
37+
response.addCookie(cookie);
38+
39+
}
40+
41+
{
42+
Cookie cookie = new Cookie("secret" ,"fakesecret");
43+
44+
// BAD: secure flag sometimes set to something clearly true or request.isSecure()
45+
boolean secureVal;
46+
if(alwaysSecure)
47+
secureVal = true;
48+
else
49+
secureVal = otherInput;
50+
cookie.setSecure(secureVal);
51+
response.addCookie(cookie);
52+
53+
}
54+
55+
{
56+
Cookie cookie = new Cookie("secret" ,"fakesecret");
57+
58+
// GOOD: set secure flag
59+
cookie.setSecure(true);
60+
response.addCookie(cookie);
61+
}
62+
63+
{
64+
Cookie cookie = new Cookie("secret" ,"fakesecret");
65+
2366
// GOOD: set secure flag
2467
cookie.setSecure(true);
2568
response.addCookie(cookie);
2669
}
70+
71+
{
72+
Cookie cookie = new Cookie("secret" ,"fakesecret");
73+
74+
// GOOD: set secure flag
75+
cookie.setSecure(constTrue);
76+
response.addCookie(cookie);
77+
}
78+
79+
{
80+
Cookie cookie = new Cookie("secret" ,"fakesecret");
81+
82+
// GOOD: set secure flag if contacted over HTTPS
83+
cookie.setSecure(alwaysSecure ? true : request.isSecure());
84+
response.addCookie(cookie);
85+
}
86+
2787
}
2888
}

0 commit comments

Comments
 (0)