Skip to content

Add security rules for cookie handling in Java applications #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions rules/java/security/cookie-httponly-false-java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
id: cookie-httponly-false-java
language: java
message: >-
A cookie was detected without setting the 'HttpOnly' flag. The
'HttpOnly' flag for cookies instructs the browser to forbid client-side
scripts from reading the cookie. Set the 'HttpOnly' flag by calling
'cookie.setHttpOnly(true);'
note: >-
[CWE-1004] Sensitive Cookie Without 'HttpOnly' Flag.
[REFERENCES]
- https://capec.mitre.org/data/definitions/463.html
rule:
pattern: $COOKIE.setHttpOnly(false);
70 changes: 70 additions & 0 deletions rules/java/security/missing-secure-java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
id: missing-secure-java
language: java
severity: warning
message: >-
Detected a cookie where the `Secure` flag is either missing or
disabled. The `Secure` cookie flag instructs the browser to forbid sending
the cookie over an insecure HTTP request. Set the `Secure` flag to `true`
so the cookie will only be sent over HTTPS.
note: >-
[CWE-614]: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute
[OWASP A05:2021]: Security Misconfiguration
[REFERENCES]
- https://owasp.org/Top10/A05_2021-Security_Misconfiguration
utils:
match_without_httponly:
kind: argument_list
has:
kind: object_creation_expression
inside:
stopBy: end
kind: method_invocation

match_cookie_last:
kind: argument_list
has:
kind: method_invocation
has:
kind: argument_list
has:
kind: string_literal

match_instance:
kind: local_variable_declaration
has:
stopBy: end
kind: identifier
follows:
stopBy: end
kind: variable_declarator

match_identifier_with_simplecookie:
kind: identifier
inside:
stopBy: end
kind: local_variable_declaration
all:
- has:
stopBy: end
kind: type_identifier
regex: '^SimpleCookie$|^Cookie$'
- has:
stopBy: neighbor
kind: variable_declarator
all:
- has:
stopBy: neighbor
kind: identifier
- has:
stopBy: neighbor
kind: object_creation_expression
- not:
precedes:
stopBy: neighbor
kind: expression_statement
rule:
any:
- matches: match_instance
- matches: match_without_httponly
- matches: match_cookie_last
- matches: match_identifier_with_simplecookie
16 changes: 16 additions & 0 deletions tests/__snapshots__/cookie-httponly-false-java-snapshot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
id: cookie-httponly-false-java
snapshots:
? |2

@RequestMapping(value = "/cookie4", method = "GET")
public void explicitDisable(@RequestParam String value, HttpServletResponse response) {
Cookie cookie = new Cookie("cookie", value);
cookie.setSecure(false);
cookie.setHttpOnly(false);
response.addCookie(cookie);
}
: labels:
- source: cookie.setHttpOnly(false);
style: primary
start: 223
end: 249
32 changes: 32 additions & 0 deletions tests/__snapshots__/missing-secure-java-snapshot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
id: missing-secure-java
snapshots:
? |
SimpleCookie s = new SimpleCookie("foo", "bar");
.orElse( new NettyCookie( "foo", "bar" ) );
Cookie z = new NettyCookie("foo", "bar");
return HttpResponse.ok().cookie(Cookie.of("zzz", "ddd"));
: labels:
- source: s
style: primary
start: 13
end: 14
- source: SimpleCookie
style: secondary
start: 0
end: 12
- source: s
style: secondary
start: 13
end: 14
- source: new SimpleCookie("foo", "bar")
style: secondary
start: 17
end: 47
- source: s = new SimpleCookie("foo", "bar")
style: secondary
start: 13
end: 47
- source: SimpleCookie s = new SimpleCookie("foo", "bar");
style: secondary
start: 0
end: 48
20 changes: 20 additions & 0 deletions tests/java/cookie-httponly-false-java-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
id: cookie-httponly-false-java
valid:
- |
@RequestMapping(value = "/cookie3", method = "GET")
public void setSecureHttponlyCookie(@RequestParam String value, HttpServletResponse response) {
Cookie cookie = new Cookie("cookie", value);
cookie.setSecure(true);
cookie.setHttpOnly(true);
response.addCookie(cookie);
}
invalid:
- |

@RequestMapping(value = "/cookie4", method = "GET")
public void explicitDisable(@RequestParam String value, HttpServletResponse response) {
Cookie cookie = new Cookie("cookie", value);
cookie.setSecure(false);
cookie.setHttpOnly(false);
response.addCookie(cookie);
}
15 changes: 15 additions & 0 deletions tests/java/missing-secure-java-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
id: missing-secure-java
valid:
- |
Cookie c1 = getCookieSomewhere();
return HttpResponse.ok().cookie(Cookie.of("foo", "bar").secure(true));
Cookie cookie = request.getCookies().findCookie( "foobar" )
Cookie c = new NettyCookie("foo", "bar");
c.secure(true);
NettyCookie r = new NettyCookie("foo", "bar").secure(true);
invalid:
- |
SimpleCookie s = new SimpleCookie("foo", "bar");
.orElse( new NettyCookie( "foo", "bar" ) );
Cookie z = new NettyCookie("foo", "bar");
return HttpResponse.ok().cookie(Cookie.of("zzz", "ddd"));