Set-Cookie HttpOnly: what it blocks in JavaScript (tested in Chrome)

HttpOnly keeps a cookie away from JavaScript while the browser keeps sending it to your server. We tested what page scripts can and can't do with it.

1. Setting it (Node, tested)

res.setHeader("Set-Cookie", [
  "session=abc123; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600",
  "theme=dark; Path=/; SameSite=Lax",
]);

2. What JavaScript on the page saw

Action in the pageResult
document.cookie"theme=dark", the session cookie is invisible
document.cookie = "session=evil; Path=/"Ignored: session stayed abc123
document.cookie = "session=evil2; Path=/; HttpOnly"Ignored: JavaScript can't create HttpOnly cookies
document.cookie = "theme=light; Path=/"Worked (not HttpOnly)
fetch("/api")Server received Cookie: session=abc123; theme=light

So an injected script (XSS) can't read or replace the session token. It can still use it, because the browser attaches the cookie to requests the script makes from your page. HttpOnly limits the damage of XSS; it doesn't prevent XSS. Pair it with a Content-Security-Policy.

3. Python (standard library, tested)

from http.cookies import SimpleCookie
c = SimpleCookie()
c["session"] = "abc123"
c["session"]["httponly"] = True
c["session"]["secure"] = True
c["session"]["samesite"] = "Lax"
c["session"]["path"] = "/"
c["session"]["max-age"] = 3600
print(c.output())

Output: Set-Cookie: session=abc123; HttpOnly; Max-Age=3600; Path=/; SameSite=Lax; Secure. Frameworks have flags for the same thing: Flask/Django httponly=True, PHP setcookie(..., ['httponly' => true]) or session.cookie_httponly=1, Spring ResponseCookie.from(...).httpOnly(true).

4. Which cookies should be HttpOnly

Check which cookies carry the flag in DevTools → Application → Cookies (HttpOnly column) or in the raw Set-Cookie response header.

Frequently asked questions

What does HttpOnly do on a cookie?

It hides the cookie from JavaScript. In our Chrome test document.cookie didn't show it, and scripts could neither overwrite it nor create one, but fetch() still sent it.

Can JavaScript set an HttpOnly cookie?

No. document.cookie = 'name=value; HttpOnly' was ignored entirely in our test. Only the server can set it, with a Set-Cookie header.

Does HttpOnly protect against XSS?

Partly: injected scripts can't steal the token, but they can still make requests that carry it. Use it together with CSP and output escaping.

How do I read an HttpOnly cookie in React?

You don't. Let the browser send it: same-origin requests include it automatically, cross-origin ones need credentials: 'include' and matching CORS headers.

Written with AI assistance. Measured on 2026-10-01 in Chromium 153 (full build): a Node 24 server set the two cookies below, then the page read and wrote document.cookie and made a fetch() while the server logged the Cookie header. The Python snippet was run on Python 3.13. Chromium accepted the Secure cookie over http://127.0.0.1 because it treats 127.0.0.1 as a secure context; on a real domain it needs HTTPS. The Flask/Django/PHP/Spring flag names are from their documentation, not this test. PlainHeaders is our extension; DevTools shows the same in the Application tab, free.