liveBook · Manning

Cross-site request forgery protection

As explained in Pro ASP.NET Core 7, Tenth Edition

A security mechanism that prevents unauthorized requests made on behalf of an authenticated user from another site.

Cross-site request forgery (CSRF) protection prevents a malicious site from causing a browser to submit an authenticated request using the victim’s session cookie. ASP.NET Core forms can emit a token cookie and a matching hidden form field; the server validates both before accepting a protected request. section 27.8

Forms generated with routing attributes such as asp-controller, asp-action, or asp-page receive the anti-forgery fields automatically when the form has no action attribute. Controllers otherwise accept POST requests without tokens, so apply AutoValidateAntiforgeryToken to validate every method except GET, HEAD, OPTIONS, and TRACE. section 27.8 section 27.8.1

Control validation according to the request surface:

  • Use ValidateAntiForgeryToken to enforce validation even for methods that normally do not require it. section 27.8.1
  • Use IgnoreAntiforgeryToken only when an action or handler deliberately needs validation suppressed. section 27.8.1 section 27.8.2
  • Razor Pages enable anti-forgery validation by default; removing an IgnoreAntiforgeryToken override restores the protection. section 27.8.2

Testing a rejected form

Open the form, use browser developer tools to remove or alter its hidden token, then submit it. The request should fail because the required token data no longer matches. section 27.8.1

Listing 27.31 Configuring the anti-forgery token in the WebApp/Program.cs file
using Microsoft.EntityFrameworkCore;
using WebApp.Models;
using Microsoft.AspNetCore.Antiforgery;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<DataContext>(opts => {
    opts.UseSqlServer(builder.Configuration[
        "ConnectionStrings:ProductConnection"]);
    opts.EnableSensitiveDataLogging(true);
});
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddSingleton<CitiesData>();

builder.Services.Configure<AntiforgeryOptions>(opts => {
    opts.HeaderName = "X-XSRF-TOKEN";
});

var app = builder.Build();

app.UseStaticFiles();

IAntiforgery antiforgery 
    = app.Services.GetRequiredService<IAntiforgery>();
app.Use(async (context, next) => {
    if (!context.Request.Path.StartsWithSegments("/api")) {
        string? token = 
            antiforgery.GetAndStoreTokens(context).RequestToken;
        if (token != null) {
            context.Response.Cookies.Append("XSRF-TOKEN",
               token,
               new CookieOptions { HttpOnly = false });
        }
    }
    await next();
});

app.MapControllerRoute("forms",
    "controllers/{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();

var context = app.Services.CreateScope().ServiceProvider
    .GetRequiredService<DataContext>();
SeedData.SeedDatabase(context);

app.Run();

Configure a JavaScript-readable XSRF-TOKEN cookie and accept the matching X-XSRF-TOKEN header through AntiforgeryOptions and middleware. section 27.8.3

JavaScript clients cannot rely on a hidden HTML input when the server returns data rather than rendered forms. Expose a readable cookie, configure the accepted header name, and copy the cookie value into that header on POST requests; frameworks such as Angular can automate this convention. section 27.8.3

How Pro ASP.NET Core 7, Tenth Edition covers it

How deep it goes
Explains token generation, controller and Razor Page defaults, validation attributes, JavaScript headers, and browser-based failure testing.
Examples
Uses a product form, altered hidden input, FormHandler Razor Page, XSRF-TOKEN cookie, and X-XSRF-TOKEN fetch header.
What it assumes
Assumes familiarity with authenticated browser requests, ASP.NET Core forms, controllers, Razor Pages, and basic JavaScript fetch calls.
What you can do after
Apply controller and page validation, test rejection by altering tokens, or configure cookie-and-header protection for JavaScript clients.
How it connects
Connects anti-forgery tokens with ASP.NET Core controllers, Razor Pages, forms tag helpers, middleware, cookies, and JavaScript clients.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro ASP.NET Core 7, Tenth Edition. The section links point to the parts of the book it draws on.