From 8e0800c94fe3d548efcde4a729f412bbe4637f8b Mon Sep 17 00:00:00 2001 From: ESS-ENN Date: Wed, 9 Oct 2024 12:36:43 +0530 Subject: [PATCH 1/2] missing-secure-java --- rules/java/security/missing-secure-java.yml | 70 +++++++++++++++++++ .../missing-secure-java-snapshot.yml | 32 +++++++++ tests/java/missing-secure-java-test.yml | 15 ++++ 3 files changed, 117 insertions(+) create mode 100644 rules/java/security/missing-secure-java.yml create mode 100644 tests/__snapshots__/missing-secure-java-snapshot.yml create mode 100644 tests/java/missing-secure-java-test.yml diff --git a/rules/java/security/missing-secure-java.yml b/rules/java/security/missing-secure-java.yml new file mode 100644 index 00000000..31a5d733 --- /dev/null +++ b/rules/java/security/missing-secure-java.yml @@ -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 diff --git a/tests/__snapshots__/missing-secure-java-snapshot.yml b/tests/__snapshots__/missing-secure-java-snapshot.yml new file mode 100644 index 00000000..3931463b --- /dev/null +++ b/tests/__snapshots__/missing-secure-java-snapshot.yml @@ -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 diff --git a/tests/java/missing-secure-java-test.yml b/tests/java/missing-secure-java-test.yml new file mode 100644 index 00000000..507f951f --- /dev/null +++ b/tests/java/missing-secure-java-test.yml @@ -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")); From 239d8348f697b4cc585c59a8ed5d84e728049bb4 Mon Sep 17 00:00:00 2001 From: ESS-ENN Date: Wed, 9 Oct 2024 12:38:14 +0530 Subject: [PATCH 2/2] missing-httponly-java --- rules/java/security/missing-httponly-java.yml | 83 +++++++++++++++++++ .../missing-httponly-java-snapshot.yml | 33 ++++++++ tests/java/missing-httponly-java-test.yml | 18 ++++ 3 files changed, 134 insertions(+) create mode 100644 rules/java/security/missing-httponly-java.yml create mode 100644 tests/__snapshots__/missing-httponly-java-snapshot.yml create mode 100644 tests/java/missing-httponly-java-test.yml diff --git a/rules/java/security/missing-httponly-java.yml b/rules/java/security/missing-httponly-java.yml new file mode 100644 index 00000000..b7d2ff64 --- /dev/null +++ b/rules/java/security/missing-httponly-java.yml @@ -0,0 +1,83 @@ +id: missing-httponly-java +language: java +severity: warning +message: >- + Detected a cookie where the `HttpOnly` flag is either missing or + disabled. The `HttpOnly` cookie flag instructs the browser to forbid + client-side JavaScript to read the cookie. If JavaScript interaction is + required, you can ignore this finding. However, set the `HttpOnly` flag to + true` in all other cases. +note: >- + [CWE-1004]: Sensitive Cookie Without 'HttpOnly' Flag + [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_cc2_cookie: + kind: local_variable_declaration + precedes: + kind: expression_statement + has: + kind: method_invocation + has: + kind: method_invocation + has: + kind: argument_list + has: + kind: string_literal + match_nettycookie: + kind: local_variable_declaration + all: + - has: + stopBy: end + kind: variable_declarator + has: + kind: object_creation_expression + all: + - has: + stopBy: end + kind: argument_list + has: + stopBy: end + kind: string_literal + precedes: + stopBy: end + kind: string_literal + - not: + precedes: + stopBy: end + kind: identifier + regex: "http" + - not: + precedes: + stopBy: neighbor + kind: expression_statement + has: + stopBy: end + kind: method_invocation + has: + stopBy: end + kind: argument_list + match_cookie_last: + kind: argument_list + has: + kind: method_invocation + has: + kind: argument_list + has: + kind: string_literal + +rule: + any: + - matches: match_cc2_cookie + - matches: match_without_httponly + - matches: match_nettycookie + - matches: match_cookie_last diff --git a/tests/__snapshots__/missing-httponly-java-snapshot.yml b/tests/__snapshots__/missing-httponly-java-snapshot.yml new file mode 100644 index 00000000..95f6dfab --- /dev/null +++ b/tests/__snapshots__/missing-httponly-java-snapshot.yml @@ -0,0 +1,33 @@ +id: missing-httponly-java +snapshots: + ? | + SimpleCookie s = new SimpleCookie("foo", "bar"); + ( new NettyCookie( "foo", "bar" ) ) + Cookie cc2 = Cookie.of("zzz", "ddd"); + Cookie z = new NettyCookie("foo", "bar"); + (Cookie.of("zzz", "ddd")) + : labels: + - source: SimpleCookie s = new SimpleCookie("foo", "bar"); + style: primary + start: 0 + end: 48 + - source: '"foo"' + style: secondary + start: 34 + end: 39 + - source: '"foo"' + style: secondary + start: 34 + end: 39 + - source: ("foo", "bar") + style: secondary + start: 33 + end: 47 + - source: new SimpleCookie("foo", "bar") + style: secondary + start: 17 + end: 47 + - source: s = new SimpleCookie("foo", "bar") + style: secondary + start: 13 + end: 47 diff --git a/tests/java/missing-httponly-java-test.yml b/tests/java/missing-httponly-java-test.yml new file mode 100644 index 00000000..bc138b5f --- /dev/null +++ b/tests/java/missing-httponly-java-test.yml @@ -0,0 +1,18 @@ +id: missing-httponly-java +valid: + - | + Cookie c1 = getCookieSomewhere(); + return HttpResponse.ok().cookie(Cookie.of("foo", "bar").httpOnly(true)); + Cookie cookie = request.getCookies().findCookie( "foobar" ) + Cookie ccc = Cookie.of("zzz", "ddd"); + ccc.httpOnly(true).secure(true); + Cookie c = new NettyCookie("foo", "bar"); + c.httpOnly(true); + NettyCookie r = new NettyCookie("foo", "bar").httpOnly(true); +invalid: + - | + SimpleCookie s = new SimpleCookie("foo", "bar"); + ( new NettyCookie( "foo", "bar" ) ) + Cookie cc2 = Cookie.of("zzz", "ddd"); + Cookie z = new NettyCookie("foo", "bar"); + (Cookie.of("zzz", "ddd"))