-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Java rule for insecure java.net.HttpCookie (#432)
Similar to javax.servlet.http.Cookie, the java.net.HttpCookie is also a class whether the contents of the cookie can be marked secure. This rule advises to always set secure to true. Signed-off-by: Eric Brown <eric.brown@securesauce.dev>
- Loading branch information
Showing
11 changed files
with
193 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- | ||
id: JAV006 | ||
title: java.net — insecure cookie | ||
hide_title: true | ||
pagination_prev: null | ||
pagination_next: null | ||
slug: /rules/JAV006 | ||
--- | ||
|
||
::: precli.rules.java.stdlib.java_net_insecure_cookie |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# Copyright 2024 Secure Saurce LLC | ||
r""" | ||
# Sensitive Cookie in HTTPS Session Without 'Secure' Attribute | ||
This rule identifies and flags any instance where cookies in Java web | ||
applications are created or set without the Secure flag. The absence of this | ||
flag allows the cookie to be transmitted over non-HTTPS connections, which | ||
poses a risk of interception by an attacker, especially through | ||
man-in-the-middle (MITM) attacks. | ||
Cookies are often used to store sensitive information such as session | ||
identifiers and personal data. When a cookie is set without the Secure flag, | ||
it can be sent over both secure (HTTPS) and insecure (HTTP) connections. | ||
This vulnerability exposes the cookie to potential interception when | ||
transmitted over an insecure connection. To mitigate this risk, the Secure | ||
flag should be set on all cookies that are intended for HTTPS sites, ensuring | ||
they are only sent via secure connections. | ||
## Example | ||
```java | ||
import java.net.HttpCookie; | ||
public class SessionCookie { | ||
public static void main(String[] args) { | ||
HttpCookie cookie = new HttpCookie("cookieName", "cookieValue"); | ||
cookie.setSecure(false); | ||
} | ||
} | ||
``` | ||
## Remediation | ||
All cookies containing sensitive data or used in a secure context must have | ||
the Secure flag enabled. This practice ensures that the cookies are | ||
transmitted only over HTTPS, providing protection against eavesdropping and | ||
MITM attacks on the communication channel. | ||
```java | ||
import java.net.HttpCookie; | ||
public class SessionCookie { | ||
public static void main(String[] args) { | ||
HttpCookie cookie = new HttpCookie("cookieName", "cookieValue"); | ||
cookie.setSecure(true); | ||
} | ||
} | ||
``` | ||
## See also | ||
- [HttpCookie (Java SE & JDK))](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/HttpCookie.html) | ||
- [CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute (PRNG)](https://cwe.mitre.org/data/definitions/614.html) | ||
_New in version 0.5.1_ | ||
""" # noqa: E501 | ||
from precli.core.call import Call | ||
from precli.core.location import Location | ||
from precli.core.result import Result | ||
from precli.rules import Rule | ||
|
||
|
||
class InsecureCookie(Rule): | ||
def __init__(self, id: str): | ||
super().__init__( | ||
id=id, | ||
name="insecure_cookie", | ||
description=__doc__, | ||
cwe_id=614, | ||
message="The cookie '{0}' was found without the 'Secure' flag " | ||
"set.", | ||
wildcards={ | ||
"java.net.*": [ | ||
"HttpCookie", | ||
], | ||
}, | ||
) | ||
|
||
def analyze_method_invocation(self, context: dict, call: Call) -> Result: | ||
if call.name_qualified not in [ | ||
"java.net.HttpCookie.setSecure", | ||
]: | ||
return | ||
|
||
argument = call.get_argument(position=0) | ||
secure = argument.value | ||
|
||
if secure is True: | ||
return | ||
|
||
fixes = Rule.get_fixes( | ||
context=context, | ||
deleted_location=Location(node=argument.node), | ||
description="Set the 'Secure' flag to True on all cookies.", | ||
inserted_content="true", | ||
) | ||
return Result( | ||
rule_id=self.id, | ||
location=Location(node=argument.node), | ||
message=self.message.format(call.var_node.text.decode()), | ||
fixes=fixes, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
15 changes: 15 additions & 0 deletions
15
tests/unit/rules/java/stdlib/java_net/examples/HttpCookieSecureFalse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// level: WARNING | ||
// start_line: 13 | ||
// end_line: 13 | ||
// start_column: 25 | ||
// end_column: 30 | ||
import java.net.*; | ||
|
||
|
||
public class HttpCookieSecureFalse { | ||
public static void main(String[] args) { | ||
HttpCookie cookie = new HttpCookie("cookieName", "cookieValue"); | ||
cookie.setHttpOnly(true); | ||
cookie.setSecure(false); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/unit/rules/java/stdlib/java_net/examples/HttpCookieSecureTrue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// level: NONE | ||
import java.net.*; | ||
|
||
|
||
public class HttpCookieSecureTrue { | ||
public static void main(String[] args) { | ||
HttpCookie cookie = new HttpCookie("cookieName", "cookieValue"); | ||
cookie.setHttpOnly(true); | ||
cookie.setSecure(true); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
tests/unit/rules/java/stdlib/java_net/test_insecure_cookie.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Copyright 2024 Secure Saurce LLC | ||
import os | ||
|
||
from parameterized import parameterized | ||
|
||
from precli.core.level import Level | ||
from precli.parsers import java | ||
from precli.rules import Rule | ||
from tests.unit.rules import test_case | ||
|
||
|
||
class InsecureCookieTests(test_case.TestCase): | ||
def setUp(self): | ||
super().setUp() | ||
self.rule_id = "JAV006" | ||
self.parser = java.Java() | ||
self.base_path = os.path.join( | ||
"tests", | ||
"unit", | ||
"rules", | ||
"java", | ||
"stdlib", | ||
"java_net", | ||
"examples", | ||
) | ||
|
||
def test_rule_meta(self): | ||
rule = Rule.get_by_id(self.rule_id) | ||
self.assertEqual(self.rule_id, rule.id) | ||
self.assertEqual("insecure_cookie", rule.name) | ||
self.assertEqual( | ||
f"https://docs.securesauce.dev/rules/{self.rule_id}", rule.help_url | ||
) | ||
self.assertEqual(True, rule.default_config.enabled) | ||
self.assertEqual(Level.WARNING, rule.default_config.level) | ||
self.assertEqual(-1.0, rule.default_config.rank) | ||
self.assertEqual("614", rule.cwe.cwe_id) | ||
|
||
@parameterized.expand( | ||
[ | ||
"HttpCookieSecureFalse.java", | ||
"HttpCookieSecureTrue.java", | ||
] | ||
) | ||
def test(self, filename): | ||
self.check(filename) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters