The fix, in one snippet
Set-Cookie: session=…; HttpOnly; Secure; SameSite=Lax; Path=/
Illustrative values. Change the paths, hostnames and options to match your own site before using it.
The sections below explain what is tested, why it matters and the alternatives.
What we test
Scan.now parses the Set-Cookie headers on the response to / and fails this check for any cookie without the HttpOnly attribute. Session and authentication cookies are highlighted (see cookie-secure-flag for the name patterns). A small number of cookies are designed to be read by script, most commonly the double-submit anti-CSRF token that Angular reads from XSRF-TOKEN and Django's csrftoken when CSRF_COOKIE_HTTPONLY is left at its default; these are listed as expected exceptions rather than failures. Scan.now only inspects headers; it does not execute page script or attempt to read cookies. As with the other cookie checks, only the anonymous response is visible, so review the cookies your application sets after login as well.
Why it matters
Cross-site scripting is the obvious route: an injected script calls document.cookie and posts the session identifier to an attacker's server, who then uses it from their own browser for as long as the session lives. HttpOnly removes the cookie from the script-visible set, so the same XSS cannot steal the session. That is a real but partial defence: the injected script can still act as the user from inside the page, submitting forms and reading responses, but it cannot persist access beyond the tab or reuse it elsewhere, and most real-world XSS payloads are simple cookie grabbers. The risk is not limited to XSS in your own code. Every third-party script on the page (analytics, chat widgets, tag managers) runs with the same access, and a compromised one, as in the 2024 polyfill.io incident, reads whatever cookies are not HttpOnly. The XSS guide and cookie flags guide give the wider picture.
How to fix it
Mark every cookie HttpOnly unless a script genuinely needs to read it:
Set-Cookie: session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax
PHP (php.ini):
session.cookie_httponly = 1
Express with express-session sets httpOnly: true by default; when setting cookies by hand:
res.cookie('session', token, { httpOnly: true, secure: true, sameSite: 'lax' });
Django: SESSION_COOKIE_HTTPONLY = True is the default; check that it has not been overridden. Spring Boot: server.servlet.session.cookie.http-only=true. ASP.NET Core: options.Cookie.HttpOnly = true in the cookie authentication options. When the application cannot be changed, add the attribute at the proxy. nginx 1.19.3+:
proxy_cookie_flags ~ httponly secure;
Apache: Header edit Set-Cookie ^(.*)$ "$1; HttpOnly". If a front-end framework needs a value that currently lives in a cookie, expose it through a meta tag or an API response instead of dropping HttpOnly from the session cookie.
Where this fits
Cookie without HttpOnly flag is check 1 of 4 that the website vulnerability scanner runs under cookie security, ordered the way they are worth fixing. That ordering is the point: Fixing this one while the check above it still fails buys less than it looks like.
What fixing this still leaves open
Cookie without HttpOnly flag closes one route in. Immediately below it: Cookie without Secure flag, where a cookie is set without the Secure attribute, so the browser will also send it over plain HTTP; Cookie without SameSite attribute, where a cookie is set without a SameSite attribute, or with SameSite=None but no Secure flag; Cookie name prefixes (__Host- / __Secure-), where session cookies do not use the __Host- or __Secure- name prefixes, so a subdomain, an HTTP origin or a lookalike path could plant a cookie that your site accepts as its own.
Found in the same scan
The website vulnerability scanner reports this alongside checks from other categories that are at least as serious, including Certificate chain and hostname validation, where the certificate presented for this hostname did not validate: The chain does not reach a trusted root, an intermediate is missing, the name does not match, or the certificate is self-signed or expired, and Exposed .env configuration file, where a .env configuration file is served from the web root. A single run of website vulnerability scanner answers all of them at once.
The first few lines
You are a senior web engineer. I ran a security and SEO scanner against my site and it reported the finding below. Fix it properly rather than suppressing the symptom.
Finding: Cookie without HttpOnly flag (medium severity)
Scanner check id: cookie-httponly-flag
The rest of this prompt names the pages and line numbers we found the problem on, the configuration to change, and the constraints a good answer has to respect. It is free, it just needs an account so the work is not scraped wholesale.
Sign in with GoogleSigning in is free and takes one click. We store your email address and nothing else.
References
Related guides
8 min read · Updated Sep 19, 2026
Cross-Site Scripting (XSS) Explained: Reflected, Stored, DOM-Based and How to Prevent It
XSS lets an attacker run their own script in your users' browsers. The three types, what an attacker does with it and the layered...
Read the guide
8 min read · Updated Sep 05, 2026
Cookie Security Flags: Secure, HttpOnly, SameSite and Cookie Prefixes
A session cookie without the right flags can be stolen over HTTP, read by injected script or sent in a forged cross-site request. Each...
Read the guide