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:
XSS (Cross-Site Scripting) → Injecting malicious JavaScript to steal cookies
Packet Sniffing → Intercepting cookies over insecure HTTP connections
Session Fixation → Forcing a user to use a known session ID
Man-in-the-Middle Attacks → Capturing cookies during transmission
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:
Always use HTTPS with secure, HttpOnly, and SameSite cookies.
Shorten cookie lifetimes and use sliding expiration.
Regenerate session IDs after login and validate security stamps.
Defend against XSS and CSRF attacks.
Enforce MFA and re-authentication for sensitive operations.
By combining these techniques, you can significantly reduce the attack surface and protect your users.