dotvitals

Cookie carries an attribute browsers cannot read

LowConfirmedQuick winweb.cookies.malformed-attribute

What this check looks for

Part of the cookie's definition is not valid. Browsers ignore the unreadable part, so the cookie may behave differently from how it was written.

Why it matters

An ignored attribute is a setting that is not applied. An unparseable expiry silently turns a persistent cookie into a session one; a misspelled SameSite value leaves the attribute unset entirely.

When the check passes, your report says: “Every attribute on the cookie is one browsers can read”.

What it costs your score

When this check fails it removes 4 points from your Web security score, before the status, confidence and repeat multipliers are applied. Web security carries a weight of 8 in the overall score.

It shares the web-security.cookies family ceiling of 30 points: however many findings that family produces, together they cannot remove more than that from Web security. One underlying problem showing up in several places is still one problem.

Severity
low
Default confidence
confirmed
Status when triggered
warn
Deduction
4 points
Family cap
web-security.cookies · 30
Category
Web security
Module
Web cookies
Fix owned by
user
In the ruleset since
2026.09

How the whole score is calculated

How to fix it

Build the cookie with the platform's cookie API rather than by hand.

An attribute the browser cannot read is a setting that is not applied.

  1. Use the framework's cookie helper instead of assembling the header string.

  2. Use Max-Age rather than Expires where you can — it is an integer and has no date-format ambiguity.

How to confirm it worked

  • curl -sSI https://‹host›/ | grep -i '^set-cookie:'

A named slot like ‹domain› — and the braces left in the configuration below — is filled in with your own values when this rule appears on a report.

Remediation by platform

nginx
# Only for a cookie from an upstream you cannot change. Fix it in the application first.
proxy_cookie_flags ~ secure httponly samesite=lax;
Apache
<IfModule mod_headers.c>
	# Workaround for a cookie from an upstream you cannot change.
	Header always edit Set-Cookie ^((?!.*;\s*Secure).*)$ "$1; Secure; HttpOnly; SameSite=Lax"
</IfModule>
Caddy
header {
	+Set-Cookie "{http.response.header.Set-Cookie}; Secure; HttpOnly"
}
Express
res.cookie('session', value, {
  secure: true,
  httpOnly: true,
  sameSite: 'lax',
  path: '/',
});
  • Requires nginx 1.19.3 or later. This rewrites cookies passing through the proxy; it cannot help for a cookie the browser receives some other way.

  • Shown because the response identified Apache. It is a last resort: set the attributes where the cookie is created. Put it in the virtual host — .htaccess runs too late to edit a header the proxy module has already emitted.

  • Also a workaround; prefer setting the attributes in the application.

Technical detail

‹detail›

RFC 6265bis §5.6 requires an unrecognised or unparseable attribute to be ignored rather than invalidating the cookie, so nothing errors — the cookie is simply set with fewer properties than intended. The usual causes are a hand-built Set-Cookie string, a date in a format the parser does not accept, or a typo in an attribute name.

Standards and references

Test this on your domain

Run the check that produces this finding, on its own, against any domain.

Open the web cookies checkerBuild the fix

Other web cookies checks