Learnitweb

HttpOnly Cookies

What Are Cookies?

A cookie is a small piece of data stored on the client’s browser, sent by the server. It is used for various purposes like:

  • Session management
  • Authentication
  • Tracking user behavior

Cookies are sent back and forth between the client and server with every request to a domain that set them.

What Is an HttpOnly Cookie?

An HttpOnly cookie is a special type of cookie that cannot be accessed or modified via JavaScript in the browser.

Declared using the HttpOnly attribute:

Set-Cookie: token=abc123; HttpOnly

Key Point:

  • Accessible only to the server
  • Not accessible to JavaScript
  • Helps prevent Cross-Site Scripting (XSS) attacks

Why Use HttpOnly Cookies?

ProblemHow HttpOnly Helps
XSS AttackPrevents JavaScript from stealing cookies
Token TheftHides tokens from browser JS (e.g., no localStorage)
Session HijackingMitigates one of the most common session-related vulnerabilities

Comparison with Other Storage Options

StorageAccessible via JSSecure by DefaultRecommended for Tokens?
localStorageYesNoNo
sessionStorageYesNoNo
HttpOnly CookieNoYes (with Secure flag)Yes

Example: Setting an HttpOnly Cookie in Spring Boot

Here’s how you can set an HttpOnly cookie after a successful login in Spring Boot:

Step 1: Return JWT Token as HttpOnly Cookie

@PostMapping("/login")
public ResponseEntity<String> login(@RequestBody LoginRequest request, HttpServletResponse response) {
    String jwtToken = jwtService.generateToken(request.getUsername());

    Cookie cookie = new Cookie("access_token", jwtToken);
    cookie.setHttpOnly(true);
    cookie.setSecure(true); // Use HTTPS in production
    cookie.setPath("/");
    cookie.setMaxAge(60 * 15); // 15 minutes

    response.addCookie(cookie);

    return ResponseEntity.ok("Login successful");
}

Explanation:

  • HttpOnly: Makes cookie inaccessible to JS.
  • Secure: Ensures cookie is sent over HTTPS only.
  • Path=/: Available across the whole domain.
  • MaxAge: Sets expiry of the cookie.

How Browser Sends HttpOnly Cookies

Once the server sets a cookie using Set-Cookie header, the browser automatically sends it with every request to that domain:

GET /api/user
Host: your-domain.com
Cookie: access_token=abc123
  • Even if JavaScript cannot see it, the browser sends it.
  • This allows seamless authentication for backend APIs.

What Happens If You Try to Read It in JavaScript?

console.log(document.cookie);
  • Does not include HttpOnly cookies
  • Your app cannot log or modify access_token stored in HttpOnly cookies

React + HttpOnly Cookies Integration

1. React Sends Credentials in Fetch Request

To include cookies in API requests:

fetch("http://localhost:8080/api/data", {
  method: "GET",
  credentials: "include" // 👈 must be set to include cookies
})

2. Spring Boot Sends JWT as HttpOnly Cookie

Cookie cookie = new Cookie("access_token", jwtToken);
cookie.setHttpOnly(true);
response.addCookie(cookie);

3. Spring Boot Validates the Cookie

@GetMapping("/api/data")
public ResponseEntity<String> getData(@CookieValue("access_token") String token) {
    if (jwtService.validateToken(token)) {
        return ResponseEntity.ok("Protected data");
    } else {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
    }
}

Best Practices for HttpOnly Cookies

PracticeWhy
Set HttpOnlyPrevents access from JS (XSS protection)
Set SecureEnsures cookie sent only over HTTPS
Use short expirationLimits risk in case of theft
Set SameSite=Strict or LaxMitigates CSRF
Rotate tokensInvalidate and refresh regularly

Common Misconceptions

MythReality
HttpOnly cookies are 100% safeThey protect from XSS but not from CSRF
JavaScript can still read HttpOnly cookiesNot possible
They make CSRF impossibleStill need CSRF protection (or use SameSite flags)

Real-World Use Case

A React frontend uses Keycloak for login:

  • Keycloak returns access_token in a secure HttpOnly cookie
  • React fetches data via APIs without manually handling tokens
  • Backend (Spring Boot) extracts and validates JWT from the cookie
  • Browser never exposes token to JavaScript → protected from token theft via XSS

Summary

FeatureHttpOnly Cookie
Accessed by JavaScript?No
Sent by browser with request?Yes
XSS-Proof?Yes
CSRF-Proof?No (use SameSite or CSRF tokens)
Best use caseStore access/refresh tokens securely
Compatible with React?Yes (use credentials: "include")