Web applications often rely on cookies to maintain user sessions after authentication. However, if cookies are stolen or hijacked, attackers can impersonate users and gain unauthorized access. Session hijacking and cookie theft are among the most common attack vectors in modern web applications.

In this article, we’ll explore how session hijacking works and the best practices in ASP.NET Core to prevent it.

What is session hijacking?

Session hijacking is when an attacker takes over a valid session by stealing session cookies. This can be done via:

Once an attacker gets hold of a session cookie, they can act as a legitimate user.

ASP.NET Core Built-in Protections

ASP.NET Core provides mechanisms to secure cookies and reduce hijacking risks. Let’s see how to configure them.

1. Use Secure Cookies

Ensure cookies are only sent over HTTPS and not accessible via JavaScript.

builder.Services.ConfigureApplicationCookie(options =>
{
    options.Cookie.HttpOnly = true; // Prevent JavaScript access
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // HTTPS only
    options.Cookie.SameSite = SameSiteMode.Strict; // Prevent CSRF
});

Best Practice: Always enforce HTTPS using app.UseHttpsRedirection();.

2. Short Session Lifetimes with Sliding Expiration

Short-lived cookies minimize the attack window.

builder.Services.ConfigureApplicationCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
    options.SlidingExpiration = true; // Refresh on activity
});

3. Regenerate Session IDs on Login

Prevent session fixation by regenerating identifiers after login.

await _signInManager.SignInAsync(user, isPersistent: false);
await _context.SaveChangesAsync();

ASP.NET Core Identity automatically issues a new cookie upon sign-in, mitigating fixation attacks.

4. Implement Cookie Authentication Validation

Periodically validate security stamps to invalidate stolen cookies.

builder.Services.Configure<SecurityStampValidatorOptions>(options =>
{
    options.ValidationInterval = TimeSpan.FromMinutes(5);
});

This ensures that if a user changes their password or logs out, old cookies become invalid.

5. Use SameSite Cookies Against CSRF

SameSite prevents cookies from being sent in cross-site requests.

options.Cookie.SameSite = SameSiteMode.Strict;

If your app requires cross-site cookies (e.g., external login providers), consider SameSite=Lax but avoid None unless absolutely necessary (and always use HTTPS).

6. Protect Against XSS (Cross-Site Scripting)

Since XSS is a common way to steal cookies:

In Program.cs:

app.Use(async (context, next) =>
{
    context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'");
    await next();
});

7. Enforce Re-authentication for Sensitive Actions

For critical operations (password change, payment, deleting account), force users to re-enter credentials or MFA.

var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
    return RedirectToAction("Login");
}

8. Use Multi-Factor Authentication (MFA)

Even if cookies are stolen, requiring a second factor makes hijacking much harder.

9. Monitor and Revoke Compromised Sessions

Log user login locations, devices, and IPs. Allow users (and admins) to view and revoke active sessions.

await _signInManager.SignOutAsync(); // Invalidate cookie

Conclusion

Session hijacking and cookie theft are real threats, but ASP.NET Core provides strong tools to mitigate them.
To secure your app:

By combining these techniques, you can significantly reduce the attack surface and protect your users.