How HTTP Works

Cookie attribute

< Set-Cookie: id=a3fWa; HttpOnly

HttpOnly Cookie Attribute: XSS Protection

Learn how the HttpOnly cookie attribute protects against XSS attacks by preventing JavaScript access to sensitive cookies.

Reviewed 2 min readbeginner3 sourcesTry itMarkdown
Default if omitted
Absent: readable via document.cookie
Accepts
Flag only, no value
Sent back to server
No: never echoed in the Cookie header
Spec
RFC 6265 §4.1.2.6, RFC 6265bis (draft)
On this page

TL;DR: HttpOnly hides a cookie from document.cookie so injected JavaScript cannot read or exfiltrate it. It does not stop XSS: the attacker’s script can still make authenticated same-origin requests, because the browser attaches the cookie on its own.

What it does

Set-Cookie: __Host-session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/

The browser still sends the cookie with every matching request, but it is excluded from document.cookie and from the Cookie Store API, and fetch/XMLHttpRequest never expose Set-Cookie response headers to scripts anyway. A script also cannot create or overwrite an HttpOnly cookie via document.cookie; the browser ignores the write.

// Server sent: Set-Cookie: session=secret; HttpOnly   and   Set-Cookie: theme=dark
console.log(document.cookie)
// "theme=dark"   (session is not listed)

What it does not do

  • It does not stop requests made as the user. With XSS on your page, fetch('/api/transfer', { method: 'POST', credentials: 'include', ... }) carries the HttpOnly cookie. SameSite does not help because the request is same-site. CSP and output encoding prevent the XSS in the first place; see Content-Security-Policy.
  • It does not hide the cookie from the user, DevTools, or a network attacker. Pair it with Secure and HTTPS.
  • It does not protect other storage. Tokens kept in localStorage or sessionStorage are always readable by script, which is the main reason session identifiers belong in HttpOnly cookies.
  • It does not stop CSRF. Use SameSite plus CSRF tokens.

Which cookies should be HttpOnly

Session IDs, refresh tokens and anything the browser merely needs to return to the server: yes. Cookies your frontend must read (for example a double-submit CSRF token the SPA copies into an X-CSRF-Token header, or a theme preference) cannot be HttpOnly.

Framework defaults

StackSettingDefault
Express (res.cookie)httpOnly: trueOff; you must set it
express-sessioncookie.httpOnlyOn
DjangoSESSION_COOKIE_HTTPONLYOn
DjangoCSRF_COOKIE_HTTPONLYOff (the CSRF cookie is meant to be readable unless you use the session-based CSRF token)
FlaskSESSION_COOKIE_HTTPONLYOn
Spring Bootserver.servlet.session.cookie.http-onlyOn
Go net/httphttp.Cookie{HttpOnly: true}Off; you must set it
PHP setcookie'httponly' => true or session.cookie_httponly=1Off
res.cookie('refresh', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  path: '/auth/refresh',
  maxAge: 7 * 24 * 60 * 60 * 1000
})

Verify

curl -sI https://example.com/login | grep -i '^set-cookie'

In Chrome DevTools, Application, Cookies, the HttpOnly column shows a check mark. In the console, document.cookie must not list the cookie name. If it does, the attribute was not on the Set-Cookie header, or a second Set-Cookie from another layer (a CDN, a different path) set a same-named cookie without it.

Frequently asked questions

What is the HttpOnly cookie attribute?

HttpOnly prevents JavaScript from accessing the cookie via document.cookie. The cookie is still sent with HTTP requests but can't be read or modified by scripts.

Does HttpOnly prevent XSS attacks?

No. HttpOnly only stops scripts from reading the cookie. Injected JavaScript can still call fetch() against your own origin, and the browser attaches the HttpOnly cookie automatically, so the attacker can act as the user while the page is open. It prevents session theft and replay from another machine, not XSS itself.

Should all cookies be HttpOnly?

Session and authentication cookies should always be HttpOnly. Cookies that JavaScript needs to read (like CSRF tokens or preferences) cannot be HttpOnly.

Can HttpOnly cookies be modified?

Not by JavaScript. They can only be set and modified by the server via Set-Cookie headers.

Sources

  1. MDN Web Docs: HttpOnlydeveloper.mozilla.org
  2. RFC 6265bis (draft): HttpOnly attributedatatracker.ietf.org
  3. OWASP: HttpOnlyowasp.org

Keep going

Browse /search