diff --git a/rules/java/security/cookie-missing-secure-flag-java.yml b/rules/java/security/cookie-missing-secure-flag-java.yml new file mode 100644 index 00000000..fc75bbb6 --- /dev/null +++ b/rules/java/security/cookie-missing-secure-flag-java.yml @@ -0,0 +1,53 @@ +id: cookie-missing-secure-flag-java +language: java +severity: warning +message: >- + A cookie was detected without setting the 'secure' flag. The 'secure' + flag for cookies prevents the client from transmitting the cookie over + insecure channels such as HTTP. Set the 'secure' flag by calling + '$COOKIE.setSecure(true);'. +note: >- + [CWE-614] Sensitive Cookie in HTTPS Session Without 'Secure' Attribute. + [REFERENCES] + - https://owasp.org/www-community/controls/SecureCookieAttribute +utils: + MATCH_RESPONSE_COOKIE_STATEMENT: + kind: expression_statement + all: + - has: + stopBy: neighbor + kind: method_invocation + all: + - has: + stopBy: neighbor + kind: identifier + regex: "response" + - has: + stopBy: neighbor + kind: identifier + regex: "addCookie" + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: identifier + - not: + follows: + stopBy: end + kind: expression_statement + all: + - has: + stopBy: end + kind: identifier + - has: + stopBy: end + kind: identifier + regex: "setSecure|setValue" + - has: + stopBy: end + kind: argument_list + +rule: + kind: expression_statement + matches: MATCH_RESPONSE_COOKIE_STATEMENT diff --git a/rules/java/security/jedis-jedisfactory-hardcoded-password-java.yml b/rules/java/security/jedis-jedisfactory-hardcoded-password-java.yml new file mode 100644 index 00000000..86150201 --- /dev/null +++ b/rules/java/security/jedis-jedisfactory-hardcoded-password-java.yml @@ -0,0 +1,248 @@ +id: jedis-jedisfactory-hardcoded-password-java +language: java +severity: warning +message: >- + A secret is hard-coded in the application. Secrets stored in source + code, such as credentials, identifiers, and other types of sensitive data, + can be leaked and used by internal or external malicious actors. Use + environment variables to securely provide credentials and other secrets or + retrieve them from a secure vault or Hardware Security Module (HSM). +note: >- + [CWE-798] Use of Hard-coded Credentials. + [REFERENCES] + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html +utils: + MATCH_PATTERN_JEDISFACTORY: + kind: expression_statement + all: + - has: + stopBy: neighbor + kind: method_invocation + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $R + - has: + stopBy: neighbor + kind: identifier + regex: "^setPassword$" + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: string_literal + - follows: + stopBy: end + kind: local_variable_declaration + all: + - has: + stopBy: neighbor + kind: type_identifier + regex: "^JedisFactory$|^jedis.ConnectionFactory$" + - has: + stopBy: neighbor + kind: variable_declarator + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $R + - has: + stopBy: neighbor + kind: object_creation_expression + - inside: + stopBy: end + kind: class_declaration + follows: + stopBy: end + kind: import_declaration + has: + stopBy: neighbor + kind: scoped_identifier + all: + - has: + stopBy: end + kind: identifier + regex: "^redis$" + - has: + stopBy: end + kind: identifier + regex: "^clients$" + + MATCH_PATTERN_CLIENT_JEDIS.JEDISFACTORY: + kind: expression_statement + all: + - has: + stopBy: neighbor + kind: method_invocation + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $R + - has: + stopBy: neighbor + kind: identifier + regex: "^setPassword$" + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: string_literal + - follows: + stopBy: end + kind: local_variable_declaration + all: + - has: + stopBy: neighbor + kind: scoped_type_identifier + all: + - has: + stopBy: neighbor + kind: scoped_type_identifier + all: + - has: + stopBy: neighbor + kind: type_identifier + regex: "^clients$" + - has: + stopBy: neighbor + kind: type_identifier + regex: "^jedis$" + - has: + stopBy: neighbor + kind: type_identifier + regex: "^JedisFactory$|^ConnectionFactory$" + - has: + stopBy: end + kind: variable_declarator + has: + stopBy: neighbor + kind: identifier + pattern: $R + - inside: + stopBy: end + kind: class_declaration + follows: + stopBy: end + kind: import_declaration + all: + - has: + stopBy: end + kind: identifier + regex: "^redis$" + - has: + stopBy: end + kind: asterisk + + MATCH_PATTERN_JEDIS.JEDISFACTORY: + kind: expression_statement + all: + - has: + stopBy: neighbor + kind: method_invocation + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $R + - has: + stopBy: neighbor + kind: identifier + regex: "^setPassword$" + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: string_literal + - follows: + stopBy: end + kind: local_variable_declaration + all: + - has: + stopBy: neighbor + kind: scoped_type_identifier + all: + - has: + stopBy: neighbor + kind: type_identifier + regex: "^jedis$" + - has: + stopBy: neighbor + kind: type_identifier + regex: "^JedisFactory$|^ConnectionFactory$" + - has: + stopBy: neighbor + kind: variable_declarator + has: + stopBy: neighbor + kind: identifier + pattern: $R + + MATCH_PATTERN_REDIS_CLIENT_JEDIS.JEDISFACTORY: + kind: expression_statement + all: + - has: + stopBy: neighbor + kind: method_invocation + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $R + - has: + stopBy: neighbor + kind: identifier + regex: "^setPassword$" + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: string_literal + - follows: + stopBy: end + kind: local_variable_declaration + all: + - has: + stopBy: neighbor + kind: scoped_type_identifier + all: + - has: + stopBy: neighbor + kind: scoped_type_identifier + all: + - has: + stopBy: end + kind: type_identifier + regex: "^redis$" + - has: + stopBy: end + kind: type_identifier + regex: "^clients$" + - has: + stopBy: end + kind: type_identifier + regex: "^jedis$" + - has: + stopBy: end + kind: type_identifier + regex: "^ConnectionFactory$|^JedisFactory$" + - has: + stopBy: neighbor + kind: variable_declarator + has: + stopBy: end + kind: identifier + pattern: $R +rule: + kind: expression_statement + any: + - matches: MATCH_PATTERN_JEDISFACTORY + - matches: MATCH_PATTERN_CLIENT_JEDIS.JEDISFACTORY + - matches: MATCH_PATTERN_JEDIS.JEDISFACTORY + - matches: MATCH_PATTERN_REDIS_CLIENT_JEDIS.JEDISFACTORY diff --git a/tests/__snapshots__/cookie-missing-secure-flag-java-snapshot.yml b/tests/__snapshots__/cookie-missing-secure-flag-java-snapshot.yml new file mode 100644 index 00000000..7eb55ce5 --- /dev/null +++ b/tests/__snapshots__/cookie-missing-secure-flag-java-snapshot.yml @@ -0,0 +1,35 @@ +id: cookie-missing-secure-flag-java +snapshots: + ? | + public class CookieController { + + @RequestMapping(value = "/cookie1", method = "GET") + public void setCookie(@RequestParam String value, HttpServletResponse response) { + Cookie cookie = new Cookie("cookie", value); + response.addCookie(cookie); + } + : labels: + - source: response.addCookie(cookie); + style: primary + start: 220 + end: 247 + - source: response + style: secondary + start: 220 + end: 228 + - source: addCookie + style: secondary + start: 229 + end: 238 + - source: cookie + style: secondary + start: 239 + end: 245 + - source: (cookie) + style: secondary + start: 238 + end: 246 + - source: response.addCookie(cookie) + style: secondary + start: 220 + end: 246 diff --git a/tests/__snapshots__/jedis-jedisfactory-hardcoded-password-java-snapshot.yml b/tests/__snapshots__/jedis-jedisfactory-hardcoded-password-java-snapshot.yml new file mode 100644 index 00000000..4a04b573 --- /dev/null +++ b/tests/__snapshots__/jedis-jedisfactory-hardcoded-password-java-snapshot.yml @@ -0,0 +1,92 @@ +id: jedis-jedisfactory-hardcoded-password-java +snapshots: + ? | + import redis.clients.jedis.JedisFactory; + + @Service + public class JedisService implements IJedisService { + @Test + public void hardcoded() { + JedisFactory jedisFactory = new JedisFactory(); + jedisFactory.setHostName(hostName); + jedisFactory.setport(port); + jedisFactory.setPassword("asdf"); + jedisFactory.setDatabase(database); + } + } + : labels: + - source: jedisFactory.setPassword("asdf"); + style: primary + start: 248 + end: 281 + - source: jedisFactory + style: secondary + start: 248 + end: 260 + - source: setPassword + style: secondary + start: 261 + end: 272 + - source: '"asdf"' + style: secondary + start: 273 + end: 279 + - source: ("asdf") + style: secondary + start: 272 + end: 280 + - source: jedisFactory.setPassword("asdf") + style: secondary + start: 248 + end: 280 + - source: JedisFactory + style: secondary + start: 136 + end: 148 + - source: jedisFactory + style: secondary + start: 149 + end: 161 + - source: new JedisFactory() + style: secondary + start: 164 + end: 182 + - source: jedisFactory = new JedisFactory() + style: secondary + start: 149 + end: 182 + - source: JedisFactory jedisFactory = new JedisFactory(); + style: secondary + start: 136 + end: 183 + - source: redis + style: secondary + start: 7 + end: 12 + - source: clients + style: secondary + start: 13 + end: 20 + - source: redis.clients.jedis.JedisFactory + style: secondary + start: 7 + end: 39 + - source: import redis.clients.jedis.JedisFactory; + style: secondary + start: 0 + end: 40 + - source: |- + @Service + public class JedisService implements IJedisService { + @Test + public void hardcoded() { + JedisFactory jedisFactory = new JedisFactory(); + jedisFactory.setHostName(hostName); + jedisFactory.setport(port); + jedisFactory.setPassword("asdf"); + jedisFactory.setDatabase(database); + } + } + style: secondary + start: 42 + end: 321 diff --git a/tests/java/cookie-missing-secure-flag-java-test.yml b/tests/java/cookie-missing-secure-flag-java-test.yml new file mode 100644 index 00000000..06940e03 --- /dev/null +++ b/tests/java/cookie-missing-secure-flag-java-test.yml @@ -0,0 +1,18 @@ +id: cookie-missing-secure-flag-java +valid: + - | + @RequestMapping(value = "/cookie2", method = "GET") + public void setSecureCookie(@RequestParam String value, HttpServletResponse response) { + Cookie cookie = new Cookie("cookie", value); + cookie.setSecure(true); + response.addCookie(cookie); + } +invalid: + - | + public class CookieController { + + @RequestMapping(value = "/cookie1", method = "GET") + public void setCookie(@RequestParam String value, HttpServletResponse response) { + Cookie cookie = new Cookie("cookie", value); + response.addCookie(cookie); + } diff --git a/tests/java/jedis-jedisfactory-hardcoded-password-java-test.yml b/tests/java/jedis-jedisfactory-hardcoded-password-java-test.yml new file mode 100644 index 00000000..8b41cdf8 --- /dev/null +++ b/tests/java/jedis-jedisfactory-hardcoded-password-java-test.yml @@ -0,0 +1,19 @@ +id: jedis-jedisfactory-hardcoded-password-java +valid: + - | + jedisFactory.setPassword(password); +invalid: + - | + import redis.clients.jedis.JedisFactory; + + @Service + public class JedisService implements IJedisService { + @Test + public void hardcoded() { + JedisFactory jedisFactory = new JedisFactory(); + jedisFactory.setHostName(hostName); + jedisFactory.setport(port); + jedisFactory.setPassword("asdf"); + jedisFactory.setDatabase(database); + } + }