Course contentsShow
← C#
Lesson 1241 of 1,90811. Identity, Security, and ClaimsFree lesson

Client-Side Token Security

Store and transmit JWTs securely in web environments without exposing them to XSS.

In this lesson, you will learn how to store and transmit JSON Web Tokens (JWTs) in web environments while minimizing the risk of Cross-Site Scripting (XSS) attacks.

The Storage Dilemma

When building web applications, you often have two primary choices for storing an access token: localStorage or HttpOnly cookies.

localStorage is easily accessible via JavaScript. If your site suffers from an XSS vulnerability—where a malicious script is injected into your page—the attacker can read localStorage.getItem('jwt') and exfiltrate your user's credentials instantly.

To mitigate this, the industry standard is to store tokens in an HttpOnly and Secure cookie. Because HttpOnly is a flag set by the server, the browser prevents client-side JavaScript from accessing the cookie. Even if an attacker executes malicious code on your site, they cannot "read" the token to steal it.

Implementing the Secure Pattern

When your C# backend authenticates a user, instead of sending the JWT back in the response body to be stored in JS memory, set it as a cookie:

Response.Cookies.Append("AuthToken", jwtString, new CookieOptions
{
    HttpOnly = true,   // Prevents JavaScript access
    Secure = true,     // Ensures cookie is sent over HTTPS only
    SameSite = SameSiteMode.Strict, // Protects against CSRF
    Expires = DateTime.UtcNow.AddMinutes(60)
});

Transmitting the Token

While this approach secures the storage, your C# backend API still needs to validate the token. Since the browser automatically includes HttpOnly cookies in requests to the domain that set them, your API can extract the token from the request header or cookie during the authentication middleware process.

Because the token is never accessible to your application's client-side JavaScript, an attacker who manages to inject a script cannot perform a "copy-paste" of the user’s session. They are limited to performing requests on behalf of the user, which can be further mitigated by SameSite cookie policies and anti-forgery tokens.

Key Takeaway: Never store JWTs in localStorage or sessionStorage because they are vulnerable to XSS; instead, use HttpOnly and Secure cookies to ensure the token remains inaccessible to client-side scripts.