Skip to content

Commit

Permalink
Add Java rule for insecure java.net.HttpCookie (#432)
Browse files Browse the repository at this point in the history
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
ericwb committed Apr 19, 2024
1 parent dacb878 commit dbb7ac4
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
| JAV003 | [java.security — weak key](rules/java/stdlib/java-security-weak-key.md) | Inadequate Encryption Strength Using Weak Keys in `java.security` Package |
| JAV004 | [java.security — weak random](rules/java/stdlib/java-security-weak-random.md) | Use of Cryptographically Weak Pseudo-Random Number Generator `SHA1PRNG` |
| JAV005 | [javax.servlet.http — insecure cookie](rules/java/stdlib/javax-servlet-http-insecure-cookie.md) | Sensitive Cookie in HTTPS Session Without 'Secure' Attribute |
| JAV006 | [java.net — insecure cookie](rules/java/stdlib/java-net-insecure-cookie.md) | Sensitive Cookie in HTTPS Session Without 'Secure' Attribute |

## Python Standard Library

Expand Down
10 changes: 10 additions & 0 deletions docs/rules/java/stdlib/java-net-insecure-cookie.md
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
103 changes: 103 additions & 0 deletions precli/rules/java/stdlib/java_net_insecure_cookie.py
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,
)
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
public class SessionCookie {
public static void main(String[] args) {
Cookie cookie = Cookie();
Cookie cookie = new Cookie("cookieName", "cookieValue");
cookie.setSecure(false);
}
}
Expand All @@ -41,7 +41,7 @@
public class SessionCookie {
public static void main(String[] args) {
Cookie cookie = Cookie();
Cookie cookie = new Cookie("cookieName", "cookieValue");
cookie.setSecure(true);
}
}
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ precli.rules.java =
# precli/rules/java/stdlib/javax_servlet_http_insecure_cookie.py
JAV005 = precli.rules.java.stdlib.javax_servlet_http_insecure_cookie:InsecureCookie

# precli/rules/java/stdlib/java_net_insecure_cookie.py
JAV006 = precli.rules.java.stdlib.java_net_insecure_cookie:InsecureCookie

precli.rules.python =
# precli/rules/python/stdlib/assert.py
PY001 = precli.rules.python.stdlib.assert:Assert
Expand Down
Empty file.
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);
}
}
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 tests/unit/rules/java/stdlib/java_net/test_insecure_cookie.py
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)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

public class CookieSecureFalse {
public static void main(String[] args) {
Cookie cookie = Cookie();
Cookie cookie = new Cookie("cookieName", "cookieValue");
cookie.setHttpOnly(true);
cookie.setSecure(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

public class CookieSecureTrue {
public static void main(String[] args) {
Cookie cookie = Cookie();
Cookie cookie = new Cookie("cookieName", "cookieValue");
cookie.setHttpOnly(true);
cookie.setSecure(true);
}
Expand Down

0 comments on commit dbb7ac4

Please sign in to comment.