What is Cross-Site Request Forgery (CSRF)?
1. What is CSRF?
Cross-Site Request Forgery (CSRF) is a web attack where an attacker tricks a user's browser into sending an unwanted request to a website where the user is already authenticated.
The key reason CSRF works is:
The browser may automatically include authentication credentials, especially cookies, when sending a request.
For example, suppose you are logged in to:
https://mybank.com
Your browser has an authentication cookie for that site.
An attacker may try to cause your browser to submit a request such as:
POST https://mybank.com/api/transfer
If the application relies only on the automatically attached cookie and has no CSRF protection, the server might treat the forged request as coming legitimately from you.
2. Simple CSRF Example
Imagine a banking application.
You log in:
User
↓
https://mybank.com/login
↓
Login successful
↓
Browser receives authentication cookie
For example:
Set-Cookie: AuthCookie=abc123
Later, while still logged in, you visit:
https://malicious-site.com
The attacker's page causes your browser to submit a request to the bank.
Conceptually:
USER
|
already logged in
|
v
mybank.com
|
Auth Cookie exists
|
v
malicious-site.com
|
tricks browser into
sending a request
|
v
mybank.com
|
Browser may automatically
include Auth Cookie
|
v
Server sees authenticated
request
That is the basic idea behind CSRF.
3. Full Simple Example
Suppose ASP.NET Core uses cookie authentication.
Program.cs
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services
.AddAuthentication(
CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "MyAuthCookie";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy =
CookieSecurePolicy.Always;
options.Cookie.SameSite =
SameSiteMode.Lax;
});
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
AccountController.cs
Simplified login example:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
[ApiController]
[Route("api/[controller]")]
public class AccountController : ControllerBase
{
[HttpPost("login")]
public async Task<IActionResult> Login()
{
var claims = new[]
{
new Claim(
ClaimTypes.Name,
"Syed")
};
var identity =
new ClaimsIdentity(
claims,
CookieAuthenticationDefaults
.AuthenticationScheme);
var principal =
new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults
.AuthenticationScheme,
principal);
return Ok();
}
}
After login, the browser receives an authentication cookie.
4. Protected Endpoint
Suppose we have:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class BankController : ControllerBase
{
[HttpPost("transfer")]
public IActionResult Transfer(
TransferRequest request)
{
return Ok(new
{
Message =
$"Transferred {request.Amount}"
});
}
}
public record TransferRequest(
decimal Amount,
string AccountNumber);
The legitimate Angular application sends:
POST /api/bank/transfer
with:
{
"amount": 10000,
"accountNumber": "ACC100"
}
Because cookie authentication is being used, the browser can automatically attach the authentication cookie.
5. Where is the Problem?
Imagine the user is still logged in.
The attacker gets the user to visit a malicious page that causes a state-changing request to the legitimate application.
The attacker does not necessarily need to know the authentication cookie.
The browser may attach it automatically when cookie rules allow it.
That distinction is fundamental.
Attacker
|
| Does NOT need to steal cookie
|
v
Victim's browser
|
| Automatically sends credentials
|
v
Legitimate Server
Therefore CSRF is about:
Forging an authenticated request
rather than necessarily stealing authentication credentials.
6. How Do We Prevent CSRF?
One traditional defense is an anti-forgery token.
The application requires two things:
Authentication Cookie
+
Anti-Forgery Token
The attacker's site may be able to trigger a request under some circumstances, but it should not be able to obtain and submit the valid anti-forgery token.
7. CSRF Token Flow
The flow is conceptually:
Angular
|
| Request/load application
v
ASP.NET Core
|
| Issues anti-forgery token
v
Angular
|
| Sends token with
| state-changing request
v
ASP.NET Core
|
| Validate token
|
+---- Invalid ----> Reject
|
+---- Valid ------> Continue
A request might contain a header such as:
X-XSRF-TOKEN: <token>
The server validates that token before accepting the state-changing operation.
8. Angular Has Built-in XSRF Support
Angular's HttpClient has support for the common cookie-to-header XSRF pattern.
By convention, Angular can read a cookie named:
XSRF-TOKEN
and send its value as:
X-XSRF-TOKEN
for eligible mutating requests.
Conceptually:
ASP.NET Core
|
| sets
v
XSRF-TOKEN cookie
|
v
Angular HttpClient
|
| reads token
v
X-XSRF-TOKEN header
|
v
ASP.NET Core
|
| compares/validates
v
Request accepted/rejected
The backend must be configured consistently with the Angular client.
9. Important: CSRF Mostly Matters When Credentials Are Sent Automatically
This is one of the most important interview points.
Suppose authentication uses a cookie:
Authentication Cookie
The browser automatically handles the cookie.
Therefore CSRF is a significant concern.
What About Bearer JWT?
Suppose Angular stores an access token and explicitly adds:
Authorization: Bearer eyJ...
using an interceptor:
const authRequest = req.clone({
setHeaders: {
Authorization:
`Bearer ${token}`
}
});
A malicious external site generally cannot cause the victim's browser to automatically attach your Angular application's bearer token as an Authorization header.
Therefore:
Bearer-token authentication where the token is explicitly attached by application JavaScript is generally not vulnerable to traditional cookie-based CSRF in the same way.
However, storing bearer tokens in browser-accessible storage creates other security considerations, especially XSS.
10. Cookie vs Bearer Token
| Authentication | CSRF concern |
|---|---|
| Authentication cookie | Yes |
| Session cookie | Yes |
| JWT stored in HttpOnly cookie | Yes |
Bearer JWT explicitly added to Authorization header |
Traditional CSRF risk is much lower |
Notice an important point:
JWT itself doesn't determine CSRF risk.
Where and how the JWT is transported matters.
For example:
JWT inside HttpOnly Cookie
↓
Browser sends automatically
↓
CSRF protection needed
But:
JWT explicitly added as:
Authorization: Bearer <token>
↓
Not automatically attached
by a malicious external page
↓
Traditional CSRF is generally
not the primary threat
11. SameSite Cookies
Modern browsers provide another important CSRF defense:
SameSite
Common values include:
Strict
Lax
None
Example:
options.Cookie.SameSite =
SameSiteMode.Lax;
SameSite=Strict
The browser applies the strongest cross-site restriction to the cookie.
SameSite=Lax
Allows the cookie in certain top-level navigation scenarios while restricting many cross-site requests.
SameSite=None
Allows cross-site cookie use and requires:
Secure
in modern browsers.
SameSite is an important defense, but the appropriate setting depends on your application's architecture.
12. HttpOnly Does NOT Prevent CSRF
This is another common interview question.
Suppose:
HttpOnly = true
This helps prevent JavaScript from directly reading the cookie.
For example:
document.cookie
cannot read an HttpOnly authentication cookie.
That's useful against some XSS-related credential theft.
But:
HttpOnlydoes not by itself prevent CSRF.
Why?
Because the browser can still automatically send the cookie with eligible requests.
HttpOnly
↓
JavaScript cannot READ cookie
but
Browser can still SEND cookie
↓
CSRF can still matter
13. XSS vs CSRF
This distinction is very important.
| XSS | CSRF |
|---|---|
| Injects/executes malicious script | Forges an unwanted request |
| Malicious code executes in trusted site's context | Request originates via victim's browser |
| Exploits unsafe content/DOM handling | Exploits automatically sent credentials |
| Angular sanitization helps | Anti-forgery tokens/SameSite help |
| Can potentially steal browser-accessible tokens | Doesn't necessarily steal credentials |
Easy way to remember
XSS
=
Attacker gets malicious CODE
to execute in your site
CSRF
=
Attacker gets your BROWSER
to send an unwanted request
14. Example with Angular + ASP.NET Core
Cookie authentication
Angular
|
| POST /api/orders
|
| Cookie automatically attached
| X-XSRF-TOKEN explicitly supplied
v
ASP.NET Core
|
| Authentication
|
| Anti-forgery validation
v
OrdersController
The server should require both valid authentication and appropriate anti-forgery protection for state-changing cookie-authenticated requests.
15. Key Points
1. CSRF means forging requests
The attacker tricks the victim's browser into performing an unwanted action on a site where the victim is authenticated.
2. Cookies are central to traditional CSRF
Because browsers can automatically attach cookies.
3. Anti-forgery tokens prevent forged requests
Typically:
Cookie/session authentication
+
CSRF token
4. Angular supports XSRF
Angular HttpClient supports the common:
XSRF-TOKEN cookie
↓
X-XSRF-TOKEN header
pattern.
5. SameSite helps
Properly configured SameSite cookies provide an additional browser-level CSRF defense.
6. HttpOnly is not CSRF protection
HttpOnly prevents JavaScript from reading the cookie; it doesn't prevent the browser from sending it.
7. JWT does not automatically mean "no CSRF"
Ask:
Where is the JWT stored and how is it sent?
JWT in an automatically sent cookie can still require CSRF protection.
16. Interview Questions and Answers
1. What is CSRF?
Answer:
CSRF is an attack where an attacker tricks an authenticated user's browser into sending an unwanted request to a trusted application. It commonly affects applications that use automatically sent authentication credentials such as cookies.
2. Why are cookie-based applications vulnerable to CSRF?
Answer:
Because browsers can automatically attach authentication cookies to requests. An attacker may therefore cause the victim's browser to send an authenticated request without knowing the cookie value.
3. How do you prevent CSRF?
Answer:
Common protections include anti-forgery tokens, properly configured SameSite cookies, validating request origin where appropriate, and avoiding unsafe state-changing GET endpoints.
4. Does Angular support CSRF protection?
Yes.
Angular HttpClient supports an XSRF cookie/header convention, commonly:
XSRF-TOKEN
↓
X-XSRF-TOKEN
The backend must validate the token.
5. Does HttpOnly prevent CSRF?
No.
HttpOnly prevents JavaScript from reading a cookie, but the browser can still automatically send the cookie with requests.
6. Is JWT authentication vulnerable to CSRF?
It depends on how the JWT is transported.
If the JWT is stored in an automatically sent cookie, CSRF protection may still be required.
If Angular explicitly attaches the JWT as:
Authorization: Bearer <token>
traditional cookie-based CSRF is generally not the main concern.
7. What is the difference between XSS and CSRF?
XSS causes malicious script to execute in the trusted application's browser context.
CSRF causes the victim's authenticated browser to send an unwanted request.
8. What does SameSite do?
SameSite controls when browsers send cookies in cross-site contexts and therefore provides an important layer of CSRF protection.
Interview Quick Answer
CSRF is an attack where an attacker tricks an authenticated user's browser into sending an unwanted request to a trusted application. It primarily matters when authentication credentials such as cookies are automatically sent by the browser. In Angular + ASP.NET Core applications using cookie authentication, CSRF can be mitigated using anti-forgery tokens, Angular's XSRF cookie/header mechanism, appropriate
SameSitecookie settings, HTTPS, and secure server-side validation.