java.lang.security.audit.cookie-missing-secure-flag.cookie-missing-secure-flag

Community Favorite
profile photo of semgrepsemgrep
Author
73,396
Download Count*

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);'

Run Locally

Run in CI

Defintion

rules:
  - id: cookie-missing-secure-flag
    metadata:
      cwe:
        - "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute"
      owasp:
        - A05:2021 - Security Misconfiguration
      source-rule-url: https://find-sec-bugs.github.io/bugs.htm#INSECURE_COOKIE
      asvs:
        section: "V3: Session Management Verification Requirements"
        control_id: 3.4.1 Missing Cookie Attribute
        control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v34-cookie-based-session-management
        version: "4"
      category: security
      technology:
        - java
      references:
        - https://owasp.org/Top10/A05_2021-Security_Misconfiguration
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cookie Security
    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);'
    severity: WARNING
    languages:
      - java
    patterns:
      - pattern-not-inside: $COOKIE.setValue(""); ...
      - pattern-either:
          - pattern: $COOKIE.setSecure(false);
          - patterns:
              - pattern-not-inside: $COOKIE.setSecure(...); ...
              - pattern-not-inside: $COOKIE = ResponseCookie.from(...). ...; ...
              - pattern: $RESPONSE.addCookie($COOKIE);

Examples

cookie-missing-secure-flag.java

@Controller
public class CookieController {

    @RequestMapping(value = "/cookie1", method = "GET")
    public void setCookie(@RequestParam String value, HttpServletResponse response) {
        Cookie cookie = new Cookie("cookie", value);
        // ruleid:cookie-missing-secure-flag
        response.addCookie(cookie);
    }

    @RequestMapping(value = "/cookie2", method = "GET")
    public void setSecureCookie(@RequestParam String value, HttpServletResponse response) {
        Cookie cookie = new Cookie("cookie", value);
        // ok:cookie-missing-secure-flag
        cookie.setSecure(true);
        response.addCookie(cookie);
    }

    @RequestMapping(value = "/cookie3", method = "GET")
    public void setSecureHttponlyCookie(@RequestParam String value, HttpServletResponse response) {
        Cookie cookie = new Cookie("cookie", value);
        // ok:cookie-missing-secure-flag
        cookie.setSecure(true);
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }

    @RequestMapping(value = "/cookie4", method = "GET")
    public void explicitDisable(@RequestParam String value, HttpServletResponse response) {
        Cookie cookie = new Cookie("cookie", value);
        // ruleid:cookie-missing-secure-flag
        cookie.setSecure(false);
        cookie.setHttpOnly(false);
        response.addCookie(cookie);
    }

    @RequestMapping(value = "/cookie5", method = "GET")
    public void explicitDisable(@RequestParam String value, HttpServletResponse response) {
	// ignore cookies created by Spring's ResponseCookie builder, since the interface is different
	Cookie cookie = ResponseCookie.from("name", "value").build();
        // ok:cookie-missing-secure-flag
        response.addCookie(cookie);
    }

    // test case cf. https://github.com/Dreampie/Resty//blob/9ef059c065d1894c79e7d69c150e588a61eb1cd5/resty-common/src/main/java/cn/dreampie/common/http/HttpResponse.java#L69
    public Response addCookie(String name, String value, int expiration, boolean httpOnly) {
    Cookie existingCookie = HttpRequest.getCookie(request.getCookies(), name);
    if (existingCookie != null) {
      if (Constant.cookiePath.equals(existingCookie.getPath())
          || existingCookie.getPath() == null // in some cases cookies set on path '/' are returned with a null path
          ) {
        // update existing cookie
        existingCookie.setPath(Constant.cookiePath);
        existingCookie.setValue(value);
        existingCookie.setMaxAge(expiration);
        if (Constant.cookieHttpOnly) {
          setHttpOnly(existingCookie);
        }
        existingCookie.setSecure(Constant.cookieSecure);
        if (Constant.cookieDomain != null) {
          existingCookie.setDomain(Constant.cookieDomain);
        }
        // ok:cookie-missing-secure-flag
        response.addCookie(existingCookie);
      } else {
        // we have an existing cookie on another path: clear it, and add a new cookie on root path
        existingCookie.setValue("");
        existingCookie.setMaxAge(0);
        // ok:cookie-missing-secure-flag
        response.addCookie(existingCookie);

        Cookie c = new Cookie(name, value);
        c.setPath(Constant.cookiePath);
        c.setMaxAge(expiration);
        if (Constant.cookieHttpOnly) {
          setHttpOnly(existingCookie);
        }
        c.setSecure(Constant.cookieSecure);
        if (Constant.cookieDomain != null) {
          c.setDomain(Constant.cookieDomain);
        }
        // ok:cookie-missing-secure-flag
        response.addCookie(c);
      }
    } else {
      Cookie c = new Cookie(name, value);
      c.setPath(Constant.cookiePath);
      c.setMaxAge(expiration);
      if (Constant.cookieHttpOnly) {
        setHttpOnly(c);
      }
      c.setSecure(Constant.cookieSecure);
      if (Constant.cookieDomain != null) {
        c.setDomain(Constant.cookieDomain);
      }
      // ok:cookie-missing-secure-flag
      response.addCookie(c);
    }
    return this;
  }

  public Response clearCookie(String cookie) {
    Cookie existingCookie = HttpRequest.getCookie(request.getCookies(), cookie);
    if (existingCookie != null) {
      existingCookie.setPath(Constant.cookiePath);
      existingCookie.setValue("");
      existingCookie.setMaxAge(0);
      // ok:cookie-missing-secure-flag
      response.addCookie(existingCookie);
    }
    return this;
  }

}