Cookie flags: Secure, HttpOnly and SameSite on Set-Cookie
SameSite=None without Secure is rejected outright, and a session cookie without HttpOnly is readable by any script. squirrel parses every Set-Cookie.
What the cookie flags are
Set-Cookie carries attributes that decide where a cookie may travel and who may read it. Secure stops the cookie being sent over plain HTTP. HttpOnly stops client-side JavaScript reading it, which closes the usual path from a cross-site scripting bug to a stolen session. SameSite decides whether the cookie rides along on requests started by other sites.
Browsers now default an absent SameSite to Lax, so omitting it is weaker documentation rather than an open door. SameSite=None is the exception: it re-enables cross-site sending for cases like an embedded widget, and browsers reject the cookie entirely unless Secure is set alongside it.
What squirrel checks
The rule reads the set-cookie response header of each crawled page, splits it into individual cookies, and emits these checks:
cookie-flagspasses when the page sets no cookies at all. Message:No cookies set on this page.cookie-samesite-none-insecurefails when a cookie declaresSameSite=NonewithoutSecure. Message:1 cookie(s) set SameSite=None without Secure — modern browsers reject this combination, with the cookie names listed.cookie-securewarns when a cookie on an HTTPS page has noSecureattribute. Message:2 cookie(s) missing the Secure flag. The check is skipped on HTTP pages, where there is no secure connection to pin the cookie to.cookie-httponlywarns when a cookie has noHttpOnlyattribute. Message:2 cookie(s) missing the HttpOnly flag.cookie-samesitereports info when a cookie declares noSameSite, or declares it with an empty value such asSameSite=. Message:2 cookie(s) don't explicitly declare SameSite (browsers default to Lax).cookie-flagspasses when cookies were set and none of the above fired. Message:3 cookie(s) set with Secure, HttpOnly, and SameSite configured correctly.
Multiple cookies in one header value are split on newlines and on commas that are followed by a name= pair, so an Expires date containing a comma does not split a cookie in two. Only cookies your server sets in a response header are seen; cookies written by JavaScript are not.
How to fix it
Set-Cookie: session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax
Set the flags where the cookie is created, in the session middleware or the framework’s cookie helper. Drop HttpOnly only for a cookie your own frontend genuinely reads, such as a CSRF token mirrored into the DOM. When you need SameSite=None, add Secure in the same change.
Only cookies your server sets in a Set-Cookie response header are inspected. A cookie written by JavaScript, whether yours or a third party’s, never reaches this rule.
| Rule ID | security/cookie-flags |
| Category | Security |
| Scope | Per-page |
| Severity | warning |
| Weight | 5/10 |
Enable / disable
Disable this rule
[rules]
disable = ["security/cookie-flags"]Disable all Security rules
[rules]
disable = ["security/*"]Enable only this rule
[rules]
enable = ["security/cookie-flags"]enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.
Related rules
- security/third-party-cookies: cookies set by domains other than yours.
- legal/cookie-consent: whether a cookie consent mechanism is present.
- security/https: the precondition for
Secureto mean anything. - security/csp: the policy that limits the injected script
HttpOnlyprotects against.
Security findings ship in every audit next to the SEO, performance and agent experience rules. See Website security scan with AI for how an agent works through a report.
References
Check your site
Run squirrel audit https://example.com and open the Security section of the report. Every cookie missing a flag is listed by name and page. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.