Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Por Fiyaz Hasan e Rick Anderson
A falsificação de solicitação entre sites é um ataque contra aplicativos hospedados na Web pelo qual um aplicativo Web mal-intencionado pode influenciar a interação entre um navegador cliente e um aplicativo Web que confia nesse navegador. Esses ataques são possíveis porque os navegadores da Web enviam alguns tipos de tokens de autenticação automaticamente a cada solicitação para um site. Essa forma de exploração também é conhecida como ataque de um clique ou sequestro de sessão porque o ataque aproveita a sessão previamente autenticada do utilizador. A falsificação de solicitação entre sites também é conhecida como XSRF ou CSRF.
Um exemplo de um ataque CSRF:
Um utilizador entra em
www.good-banking-site.example.comusando a autenticação por formulários. O servidor autentica o usuário e emite uma resposta que inclui uma autenticação cookie. O site é vulnerável a ataques porque confia em qualquer solicitação recebida com uma autenticação válida cookie.O utilizador visita um site malicioso,
www.bad-crook-site.example.com.O site mal-intencionado,
www.bad-crook-site.example.com, contém um formulário HTML semelhante ao exemplo a seguir:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>Observe que o
actiondo formulário envia informações para o site vulnerável, não para o site malicioso. Esta é a parte "cross-site" da CSRF.O usuário seleciona o botão enviar. O navegador faz a solicitação e inclui automaticamente a autenticação cookie para o domínio solicitado,
www.good-banking-site.example.com.A solicitação é executada no servidor
www.good-banking-site.example.comcom o contexto de autenticação do usuário e pode executar qualquer ação que um usuário autenticado tenha permissão para executar.
Além do cenário em que o usuário seleciona o botão para enviar o formulário, o site mal-intencionado pode:
- Execute um script que envia automaticamente o formulário.
- Envie o envio do formulário como uma solicitação AJAX.
- Oculte o formulário usando CSS.
Esses cenários alternativos não exigem nenhuma ação ou entrada do usuário além de visitar inicialmente o site mal-intencionado.
O uso de HTTPS não impede um ataque CSRF. O site mal-intencionado pode enviar uma solicitação https://www.good-banking-site.example.com/ tão facilmente quanto pode enviar uma solicitação insegura.
Alguns ataques têm como alvo endpoints que respondem a solicitações GET, caso em que uma etiqueta de imagem pode ser usada para executar a ação. Esta forma de ataque é comum em sites de fóruns que permitem imagens, mas bloqueiam JavaScript. Os aplicativos que mudam de estado em solicitações GET, onde variáveis ou recursos são alterados, são vulneráveis a ataques mal-intencionados. As solicitações GET que mudam de estado são inseguras. Uma prática recomendada é nunca alterar o estado em uma solicitação GET.
Os ataques CSRF são possíveis contra aplicativos da Web que usam cookies para autenticação porque:
- Os navegadores armazenam cookies emitidos por um aplicativo da Web.
- Os cookies armazenados incluem cookies de sessão para utilizadores autenticados.
- Os navegadores enviam todos os cookies associados a um domínio para o aplicativo Web a cada solicitação, independentemente de como a solicitação para o aplicativo foi gerada dentro do navegador.
No entanto, os ataques CSRF não se limitam a explorar cookies. Por exemplo, as autenticações Basic e Digest também são vulneráveis. Depois que um usuário entra com autenticação Básica ou Digest, o navegador envia automaticamente as credenciais até que a sessão termine.
Neste contexto, sessão refere-se à sessão do lado do cliente durante a qual o usuário é autenticado. Não está relacionado com sessões do lado do servidor nem com middleware de sessões ASP.NET Core.
Os usuários podem se proteger contra vulnerabilidades CSRF tomando precauções:
- Saia dos aplicativos Web quando terminar de usá-los.
- Limpe os cookies do navegador periodicamente.
No entanto, as vulnerabilidades CSRF são fundamentalmente um problema com o aplicativo Web, não com o usuário final.
Fundamentos de autenticação
A autenticação baseada em Cookieé uma forma popular de autenticação. Os sistemas de autenticação baseados em tokens estão crescendo em popularidade, especialmente para aplicativos de página única (SPAs).
Autenticação baseada em Cookie
Quando um usuário se autentica usando seu nome de usuário e senha, ele recebe um token contendo um tíquete de autenticação. O token pode ser usado para autenticação e autorização. O token é armazenado como um cookie que é enviado a cada solicitação feita pelo cliente. A geração e validação disto cookie é feita através do cookie middleware de autenticação. O middleware serializa uma entidade de usuário em um cookiecriptografado. Em solicitações subsequentes, o middleware valida o cookie, recria o principal e atribui o principal à propriedade HttpContext.User.
Autenticação baseada em tokens
Quando um usuário é autenticado, ele recebe um token (não um token antifalsificação). O token contém informações do usuário na forma de declarações ou um token de referência que aponta o aplicativo para o estado do usuário mantido no aplicativo. Quando um usuário tenta acessar um recurso que requer autenticação, o token é enviado para o aplicativo com um cabeçalho de autorização extra na forma de um token de portador. Essa abordagem torna a aplicação sem estado. Em cada solicitação subsequente, o token é passado na solicitação de validação do lado do servidor. Este token não é criptografado; é codificado. No servidor, o token é decodificado para acessar suas informações. Para enviar o token em solicitações subsequentes, armazene-o no armazenamento local do navegador. Colocar um token no armazenamento local do navegador e recuperá-lo e usá-lo como um token de portador fornece proteção contra ataques CSRF. No entanto, se o aplicativo estiver vulnerável à injeção de script via XSS ou a um arquivo JavaScript externo comprometido, um ciberinvasor poderá recuperar qualquer valor do armazenamento local e enviá-lo para si mesmo. ASP.NET Core codifica todas as saídas do lado do servidor de variáveis por padrão, reduzindo o risco de XSS. Se substituir este comportamento usando Html.Raw ou códigos personalizados com entradas não confiáveis, poderá aumentar o risco de XSS.
Não se preocupe com a vulnerabilidade CSRF se o token estiver armazenado no armazenamento local do navegador. CSRF é uma preocupação quando o token é armazenado num cookie. Para obter mais informações, consulte o problema da GitHub , onde o exemplo de código SPA adiciona dois cookies.
Vários aplicativos hospedados em um domínio
Os ambientes de alojamento partilhado são vulneráveis a sequestro de sessão, CSRF no início de sessão e outros ataques.
Embora example1.contoso.net e example2.contoso.net sejam hosts diferentes, há uma relação de confiança implícita entre hosts sob o domínio *.contoso.net. Essa relação de confiança implícita permite que hosts potencialmente não confiáveis afetem os cookies uns dos outros (as políticas de mesma origem que regem as solicitações AJAX não se aplicam necessariamente aos cookies HTTP).
Os ataques que exploram cookies confiáveis entre aplicativos hospedados no mesmo domínio podem ser evitados não compartilhando domínios. Quando cada aplicativo é hospedado em seu próprio domínio, não há nenhuma relação de confiança implícita cookie para explorar.
Cabeçalhos de metadados de fetch
Os navegadores modernos incluem cabeçalhos de pedido Fetch Metadata — sobretudo Sec-Fetch-Site — em todos os pedidos.
Sec-Fetch-Site Descreve a relação entre a origem que iniciou o pedido e a origem que está a ser solicitada: same-origin identifica um pedido que o site fez a si próprio, enquanto same-site e cross-site identifica pedidos iniciados por outra origem. O cabeçalho Origin inclui a origem iniciadora e serve como alternativa para navegadores anteriores aos metadados de Fetch.
Sec-Fetch-Site e Origin são cabeçalhos de pedido proibidos: o navegador define-os, e o JavaScript a correr numa página não pode sobrepê-los nem falsificá-los. Isso torna-os um sinal fiável para distinguir os pedidos do próprio site dos pedidos entre sites sem um token emitido pelo servidor. A proteção automática CSRF incorporada no ASP.NET Core usa este sinal para rejeitar publicações de formulários cross-site que não são explicitamente confiáveis.
Proteção CSRF automática no ASP.NET Core
O ASP.NET Core disponibiliza um middleware automático de proteção CSRF que está ativado por defeito em aplicações construídas com WebApplication.CreateBuilder. Ao contrário do sistema antifalsificação baseado em tokens, este middleware não emite nem valida tokens. Em vez disso, inspeciona o Sec-Fetch-Site e os Origincabeçalhos de metadados Fetch e regista um veredicto de validação relativamente ao pedido. Os componentes que processam os dados enviados através do formulário aplicam essa decisão, rejeitando submissões de formulários de origem cruzada que não sejam explicitamente autorizadas.
Para a maioria das aplicações, não são necessárias alterações de código: pedidos de navegador da mesma origem, métodos HTTP seguros e clientes não-navegador (curlservidor-para-servidor, aplicações móveis) passam todos sem serem afetados. O middleware afeta principalmente aplicações que aceitam publicações de formulários de origem cruzada a partir de um navegador, como um site que publica um formulário numa API numa origem diferente. Esses cenários precisam de configurar o CORS para declarar a origem confiável ou optar por não usar o endpoint.
Este middleware é aditivo ao sistema antifalsificação baseado em tokens. As duas proteções coexistem e podem ambas estar ativas no mesmo ponto final. Para comparar os casos em que cada um se aplica, veja Interação com a proteção antifalsificação baseada em tokens.
Como funciona
Para cada pedido, o middleware avalia uma curta cadeia de regras para chegar a um veredicto — permitido ou recusado. Os testes decorrem por ordem e o primeiro jogo vence:
-
Os métodos HTTP seguros são sempre permitidos. Os pedidos
GET,HEAD,OPTIONSeTRACEpassam. Isto segue a RFC 9110 §9.2.1 e é consistente com a regra antiga de que os endpoints não devem mudar de estado emGET. -
Sec-Fetch-Site: same-originouSec-Fetch-Site: noneé permitido. Os navegadores modernos enviamSec-Fetch-Siteem cada pedido.same-originCobre a navegação e busca normais dentro da aplicação, enonecobre pedidos iniciados diretamente pelo utilizador (ao escrever um URL, usando um favorito). Este é o caminho de código mais comum — a maior parte do tráfego legítimo do navegador sai aqui. - Uma origem confiável do CORS é permitida. Se o pedido incluir um cabeçalho
Origine a política CORS resolvida do ponto final confiar nessa origem, o pedido é permitido. O middleware resolve a política da mesma forma que o middleware CORS: primeiro, a política por endpoint de[EnableCors("name")]e, em seguida, a política predefinida registada comAddDefaultPolicy. Consulte Permitir clientes de origem cruzada para limites importantes desta regra. - Qualquer outro
Sec-Fetch-Sitevalor é negado. QuandoSec-Fetch-Siteiscross-siteousame-sitee a origem não é confiável via CORS, o pedido é negado. -
Não
Sec-Fetch-Site, masOriginestá presente: o middleware compara oOrigincomscheme://host[:port]construído a partir do pedido. Se coincidirem, o pedido é aceite; caso contrário, é negado. Esta é a alternativa de recurso para navegadores anteriores à especificação Fetch Metadata (publicada por volta de 2020). - Sem
Sec-Fetch-Sitee semOrigin: a solicitação é permitida. Os navegadores enviam sempre pelo menos um destes num pedido de escrita, por isso um pedido sem ambos é quase certamente um cliente que não seja do navegador, comocurl, Postman, uma aplicação móvel ou um chamador servidor-para-servidor. O CSRF é um vetor de ataque exclusivo do navegador, pelo que estes pedidos passam.
O middleware regista este veredicto sobre o pedido em vez de terminar o pedido em si. Para saber como e quando um veredicto negado se transforma numa resposta HTTP 400 Bad Request , veja Validação diferida.
Validação diferida
O middleware não rejeita um pedido por si só. Em vez disso, regista o seu veredicto sobre o IAntiforgeryValidationFeaturepedido — a mesma funcionalidade que o sistema antifalsificação baseado em tokens utiliza — onde um veredicto negado é registado como inválido. O pedido continua a avançar. Um veredicto inválido torna-se HTTP 400 Bad Request apenas quando um componente que processa dados de formulário o observa. Este adiamento está em conformidade com a forma como o sistema baseado em tokens já se comporta: o veredicto é gerado antecipadamente, mas só é aplicado no momento em que um formulário é utilizado.
Os seguintes componentes leem IAntiforgeryValidationFeature e rejeitam um pedido com 400 - Bad Request quando o veredicto registado é inválido:
- Ações MVC protegidas por antifalsificação.
- Endpoints mínimos de API que associam um parâmetro de formulário.
- Blazor pontos de extremidade SSR.
- Qualquer código que leia diretamente o formulário de pedido, que atua como um backstop.
Cada consumidor verifica primeiro se um middleware anti-falsificação ou CSRF foi efetivamente executado antes de confiar no resultado, pelo que um pipeline sem qualquer um desses middleware não produz falsas rejeições.
Uma consequência deste modelo é que um endpoint que nunca lê dados do formulário corre mesmo quando o veredicto é inválido. Por exemplo, um endpoint da API JSON que associa o seu corpo a partir do JSON, ou um handler que ignora o corpo do pedido, não é rejeitado automaticamente num pedido cross-origin. O veredicto continua a ser registado em IAntiforgeryValidationFeature para o código que o queira inspecionar, mas nada o impõe. O CSRF é um vetor de ataque baseado em formulários e emcookie, pelo que os endpoints que não processam um formulário enviado pelo navegador geralmente não precisam desta rejeição. Os endpoints que processam formulários — Razor Páginas, views MVC, Blazor SSR e associação de formulários em Minimal API — obtêm a proteção automaticamente.
Comportamento padrão
O middleware é registado automaticamente por WebApplication.CreateBuilder e é executado após a autenticação e a autorização. Valida cada pedido usando a implementação registada ICsrfProtection , que por defeito aplica as regras descritas em Como funciona. A implementação padrão pode ser substituída; ver Personalização: implementar ICsrfProtection. Para desligar completamente o middleware, veja Desabilitar globalmente.
O resultado é que uma aplicação mínima com um endpoint de gestão de formulários, como os seguintes, já está protegida:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapPost("/widgets", ([FromForm] Widget w) =>
Results.Created($"/widgets/{w.Id}", w));
app.Run();
Um navegador que faz um pedido POST /widgets de mesma origem acede normalmente ao endpoint. Um navegador em https://attacker.example.com que submete o mesmo formulário é rejeitado com 400 - Bad Request quando o endpoint faz a associação dos dados do formulário, antes de o corpo do processador ser executado. Um curl pedido sem Sec-Fetch-Site ou Origin é permitido.
Como a rejeição é adiada para os consumidores de formulários, um endpoint que não lê dados de formulário — como uma API JSON que mapeia o corpo a partir de JSON — não é rejeitado automaticamente, mesmo num pedido entre origens. O veredicto continua registado no pedido de código que pretende inspecioná-lo.
O middleware integra-se com o modelo antifalsificação existente:
-
APIs mínimas: Chamar
.DisableAntiforgery()num endpoint exclui esse endpoint de ambos o middleware baseado em tokens e o middleware de proteção CSRF. Os mesmos metadados (IAntiforgeryMetadata { RequiresValidation = false }) são verificados por ambos. -
Controladores e ações do MVC:
[IgnoreAntiforgeryToken]Também exclui o endpoint de ambas as proteções.
Permitir clientes de origens diferentes
O cenário mais comum que requer ação é um cliente baseado em navegador que submete um formulário de origem cruzada — por exemplo, um site ao https://app.contoso.com publicar um formulário numa API em https://api.contoso.com. Submissões de formulários deste tipo são recusadas por predefinição porque Sec-Fetch-Site é same-site ou cross-site em vez de same-origin, e o consumidor do formulário impõe essa decisão com um 400 - Bad Request.
O middleware CSRF não introduz a sua própria lista de confiança. Reutiliza a mesma política CORS que o middleware CORS determina para o ponto final: se essa política permitir o Origin do pedido, o middleware CSRF regista uma decisão favorável para o pedido.
A política é selecionada para cada endpoint por esta ordem:
-
[EnableCors("api")](MVC) ou.RequireCors("api")(API Mínima) → a política nomeada"api". - Não há metadados CORS no endpoint → a política padrão registada com
AddDefaultPolicy. - Nenhuma política correspondente (política nomeada não registada, sem política predefinida ou
services.AddCors()nunca chamada) → sem confiança derivada de CORS. O middleware fica sujeito aSec-Fetch-Sitee às regras Origin-vs-Host.
Um exemplo mínimo usando uma política padrão e um endpoint API Minimal:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
policy.WithOrigins("https://app.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod());
});
var app = builder.Build();
app.UseCors();
app.MapPost("/widgets", ([FromForm] Widget w) =>
Results.Created($"/widgets/{w.Id}", w));
app.Run();
Para uma política nomeada num único endpoint:
app.MapPost("/widgets", ([FromForm] Widget w) => Results.Created($"/widgets/{w.Id}", w))
.RequireCors("api");
Advertência
AllowAnyOrigin não é intencionalmente considerado um sinal de confiança para CSRF.
AllowAnyOrigin significa "qualquer navegador pode ler este recurso", o que é uma preocupação diferente de "qualquer origem pode alterar o estado em nome do utilizador". Tratar AllowAnyOrigin como sendo de confiança transformaria este middleware numa operação nula para escritas entre origens. As aplicações que precisam de uma política CORS de leitura pública, combinada com operações de escrita protegidas por CSRF, devem listar explicitamente origens de escrita de confiança com WithOrigins ou optar por excluir os endpoints de escrita se não dependerem de autenticação baseada em cookie.
[DisableCors] num endpoint não é uma opção de exclusão do CSRF. Ignora a etapa de confiança derivada do CORS, e o pedido ainda tem de cumprir as Sec-Fetch-Site regras Origin-vs-Host. Para desativar a proteção contra CSRF, consulte Excluir um ponto final.
Para obter detalhes sobre a configuração do próprio CORS — AddCors, AddDefaultPolicy, AddPolicy, WithOrigins e o restante da API de criação de políticas — consulte Ativar pedidos entre origens (CORS) no ASP.NET Core.
Optar por excluir um endpoint
Se um endpoint não for acessível a partir do navegador ou estiver protegido por um mecanismo que não seja cookie, como um token bearer ou uma chave de API, exclua-o individualmente em vez de desativar globalmente o middleware.
APIs mínimas — chamar DisableAntiforgery o endpoint ou grupo:
app.MapPost("/api/webhook", (WebhookPayload p) => Results.Accepted())
.DisableAntiforgery();
Controladores MVC — aplicar [IgnoreAntiforgeryToken] à ação ou ao controlador:
[ApiController]
[Route("api/[controller]")]
[IgnoreAntiforgeryToken]
public class WebhookController : ControllerBase
{
[HttpPost]
public IActionResult Post([FromBody] WebhookPayload payload) => Accepted();
}
Qualquer uma das abordagens adiciona IAntiforgeryMetadata { RequiresValidation = false } ao endpoint, que é respeitado pelo middleware CSRF, ignorando a validação.
Advertência
Desativar a proteção contra CSRF num endpoint só deve ser feito quando o endpoint não for vulnerável a ataques CSRF — por exemplo, endpoints que não são acessíveis a partir de um navegador ou que estão protegidos com autenticação não-cookie, como tokens ao portador ou chaves de API. Não desative a proteção CSRF em endpoints acessíveis ao navegador que dependem de cookies para autenticação.
Desativar globalmente
O middleware pode ser desativado em toda a aplicação usando a DisableCsrfProtection chave de configuração. Isto é uma solução de recurso — prefira desativações ao nível de cada endpoint.
Em appsettings.json:
{
"DisableCsrfProtection": true
}
Ou como variável de ambiente:
ASPNETCORE_DisableCsrfProtection=true
Quando esta chave está definida para true, WebApplication não regista o middleware no pipeline. O ICsrfProtection serviço mantém-se registado, por isso tudo o que o resolve diretamente continua a funcionar.
Advertência
O middleware CSRF automático também cumpre o requisito de proteção antifalsificação para endpoints que exigem validação, mesmo quando a aplicação não chama app.UseAntiforgery(). Se uma aplicação depende de antifalsificação, mas não chama app.UseAntiforgery(), desativar globalmente o middleware CSRF ou executá-la num anfitrião que não seja criado com WebApplication, em que o middleware não é injetado, deixa esses pontos finais sem middleware de antifalsificação. Um pedido a esse ponto terminal gera então uma exceção. Chama app.UseAntiforgery() nessa configuração.
Suporte de navegador
Sec-Fetch-Site é suportado por todas as versões atuais dos navegadores baseados em Chromium, Firefox e Safari. Para uma tabela de compatibilidade oficial, consulte a referência da MDN para Sec-Fetch-Site.
Navegadores mais antigos anteriores aos Metadados Fetch não enviam Sec-Fetch-Site. Para esses clientes, o middleware recorre à comparação do cabeçalho Origin com o esquema e o host do pedido. Os navegadores têm enviado Origin em pedidos de escrita entre origens há muitos anos, por isso esta alternativa cobre essencialmente todo o tráfego de navegadores antigos.
Clientes não baseados em navegador—curl, Postman, aplicações móveis e chamadas de servidor para servidor—normalmente não enviam nem Sec-Fetch-Site nem Origin. Esses pedidos são permitidos porque o CSRF é um vetor de ataque exclusivo do navegador que depende do navegador anexar automaticamente credenciais ambientes, como cookies. Um cliente que não seja navegador e que queira atacar a API não precisa de CSRF; pode simplesmente ligar diretamente à API com as credenciais que possui.
Personalização: implementar ICsrfProtection
A lógica de decisão está por trás de uma interface com um único método:
namespace Microsoft.AspNetCore.Antiforgery;
public interface ICsrfProtection
{
ValueTask<CsrfProtectionResult> ValidateAsync(HttpContext context);
}
Para substituir a implementação predefinida, registe um singleton na DI. Como o framework usa TryAddSingleton, uma chamada explícita AddSingleton sobrepõe-se ao padrão:
builder.Services.AddSingleton<ICsrfProtection, AllowlistCsrfProtection>();
Uma implementação personalizada é útil quando o modelo de confiança não se ajusta ao CORS — por exemplo, quando se prefere uma lista fixa de origens de parceiros, ou quando são necessárias regras mais rigorosas:
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Http;
public sealed class AllowlistCsrfProtection : ICsrfProtection
{
private static readonly HashSet<string> SafeMethods =
new(StringComparer.OrdinalIgnoreCase) { "GET", "HEAD", "OPTIONS", "TRACE" };
private static readonly HashSet<string> TrustedOrigins =
new(StringComparer.OrdinalIgnoreCase)
{
"https://app.contoso.com",
"https://admin.contoso.com",
};
public ValueTask<CsrfProtectionResult> ValidateAsync(HttpContext context)
{
if (SafeMethods.Contains(context.Request.Method))
{
return ValueTask.FromResult(CsrfProtectionResult.Allowed());
}
var origin = context.Request.Headers.Origin.ToString();
var allowed = !string.IsNullOrEmpty(origin) && TrustedOrigins.Contains(origin);
return ValueTask.FromResult(
allowed ? CsrfProtectionResult.Allowed() : CsrfProtectionResult.Denied());
}
}
O middleware continua a respeitar .DisableAntiforgery() / [IgnoreAntiforgeryToken] independentemente de qual implementação estiver registada — a desativação é gerida pelo próprio middleware antes de ValidateAsync ser chamado.
Interação com a proteção antifalsificação baseada em token
As duas defesas CSRF visam camadas diferentes e são concebidas para coexistir. Partilham também a mesma funcionalidade de pedido: ambos registam o resultado em IAntiforgeryValidationFeature, e os consumidores do formulário fazem cumprir o veredicto presente.
| Aspect | Baseado em token AntiforgeryMiddleware |
Middleware de proteção automática contra CSRF |
|---|---|---|
| Introdução | ASP.NET Core 2.0+ | .NET 11 |
| Activation | Opt-in através de app.UseAntiforgery() (ou implicitamente através de AddMvc / MapRazorPages / AddRazorComponents) |
Injetado automaticamente por WebApplication.CreateBuilder |
| Valida | Token sincronizado (campo de formulário + par cookie) |
Sec-Fetch-Site
/
Origin cabeçalhos |
| Requires | Visão geral da Proteção de Dados ASP.NET Core para encriptação de tokens | Sem tokens, sem estado |
| Âmbito do navegador | Todos os navegadores que enviam cookies | Todos os navegadores modernos; Origin alternativa para sistemas legados |
| Desativação para cada ponto terminal | .DisableAntiforgery() / [IgnoreAntiforgeryToken] |
O mesmo — ambos respeitam os mesmos metadados |
O middleware baseado em tokens protege especificamente contra o padrão clássico de ataque CSRF, em que um site malicioso desencadeia um formulário POST para um site vulnerável usando os cookies ambientes do utilizador. O middleware automático CSRF aborda a mesma ameaça na camada HTTP usando metadados fornecidos pelo navegador. Ambos podem estar ativos no mesmo endpoint, e muitas aplicações beneficiam de defesa em profundidade:
- Razor As aplicações Pages, MVC e Blazor SSR que já utilizam o sistema de tokens recebem uma verificação baseada em cabeçalho que é executada antes da validação do token, sem alterar o fluxo do token.
-
Aplicações de API mínimas que fazem associação de formulários têm um comportamento predefinido útil sem ser necessário chamar
app.UseAntiforgery()ou propagarIAntiforgeryatravés dos pontos finais. - As APIs invocadas por SPAs de origem cruzada podem recorrer a este middleware combinado com uma lista de permissões de CORS e prescindir totalmente do sistema de tokens se a API nunca fornecer formulários HTML.
O middleware automático CSRF substitui o sistema baseado em tokens em muitos cenários, porque ambos protegem os mesmos endpoints de tratamento de formulários. Mantenha o sistema baseado em tokens quando:
- A aplicação deve suportar navegadores que não enviem
Sec-Fetch-Site. Veja Suporte ao navegador. - A aplicação utiliza IAntiforgeryAdditionalDataProvider a transferência de dados extra dentro do token.
- Um requisito de revisão de segurança ou conformidade especifica a defesa do token como uma camada independente.
Para detalhes sobre o sistema baseado em tokens, incluindo integração de formulários, fluxos AJAX, configuração via AntiforgeryOptions, e IAntiforgery APIs, consulte Antiforgery no ASP.NET Core.
A validação de tokens tem prioridade
Quando uma aplicação chama app.UseAntiforgery(), o middleware baseado em tokens corre depois do middleware automático CSRF. O middleware de token elimina qualquer veredicto registado pelo middleware CSRF e substitui-o pelo resultado da validação do token. O resultado do token é autoritativo:
- Um pedido que o middleware CSRF assinalou como inválido torna-se válido se incluir um token válido.
- Um pedido permitido pelo middleware CSRF é marcado como inválido se o seu token estiver em falta ou inválido.
Esta ordenação significa que as aplicações que usam o sistema de tokens têm o mesmo comportamento de ponta a ponta que tinham antes de existir o middleware automático, enquanto as aplicações que não usam tokens ficam sujeitas à decisão do middleware CSRF.
Blazor Renderização estática do lado do servidor
Blazor os endpoints de renderização estática do lado do servidor (SSR) participam no mesmo modelo diferido. O Razor endpoint Components confia no veredito registado IAntiforgeryValidationFeature pelo middleware a montante e só retorna 400 - Bad Request para um post de formulário quando esse veredicto for inválido. O endpoint já não valida o pedido em si.
O comportamento depende de qual middleware foi executado:
- As aplicações que chamam
app.UseAntiforgery()não sofrem alterações. O middleware baseado em tokens valida cada pedido, e são gerados tokens anti-falsificação para os formulários apresentados, tal como anteriormente. - As aplicações que não invocam
app.UseAntiforgery()são, em vez disso, protegidas pelo middleware CSRF automático. Nessa configuração, o ponto final omite a geração do token de antifalsificação porque não existe nenhum middleware de tokens para validar um token num pedido posterior.
Esta é uma alteração de comportamento do SSR estático que anteriormente removia app.UseAntiforgery(): passa agora a ser protegido pelo middleware de CSRF, em vez de ficar desprotegido, e deixa de emitir tokens anti-falsificação. Para orientações sobre migração, consulte Migrar do ASP.NET Core em .NET 10 para ASP.NET Core em .NET 11. Para o aviso formal de alteração de quebra, vejaBlazor a renderização do lado do servidor adia a validação antifalsificação para middleware.
Troubleshooting
Sintoma: Pedidos de mesma origem provenientes de um navegador têm sucesso, mas as publicações de formulários de origem cruzada retornam 400 - Bad Request sem corpo.
Causa: O middleware CSRF registou um veredicto inválido para o pedido de origem cruzada, e um componente de processamento de formulários — como uma ação MVC, uma ligação de formulário Minimal API ou um Blazor post de formulário SSR — aplicou esse veredicto com um 400 - Bad Request. Este é o comportamento predefinido esperado para endpoints que processam formas.
Resolução: Escolha um dos seguintes, dependendo do cenário:
- Se a origem do chamador for conhecida e confiável, permita-o via CORS.
- Se o endpoint não estiver acessível através do navegador ou utilizar autenticação que não seja cookie, exclua-o com
.DisableAntiforgery()ou[IgnoreAntiforgeryToken]. - Se toda a aplicação precisar de optar por sair (por exemplo, durante uma janela de migração), desative globalmente.
Diagnosticar: O middleware regista todos os veredictos inválidos ao nível Debug, na categoria Microsoft.AspNetCore.Antiforgery.CsrfProtectionMiddleware, com o nome de evento CsrfValidationFailed. Ative Debug o registo para essa categoria em appsettings.Development.json:
{
"Logging": {
"LogLevel": {
"Microsoft.AspNetCore.Antiforgery.CsrfProtectionMiddleware": "Debug"
}
}
}
Um veredicto registado aparece então no registo como:
dbug: Microsoft.AspNetCore.Antiforgery.CsrfProtectionMiddleware[1]
Cross-origin CSRF protection marked request POST /widgets from origin 'https://attacker.example.com' as invalid.
Reproduzir localmente: Utilize curl com um cabeçalho Origin explícito para simular um pedido do navegador entre origens num endpoint de formulário:
curl -i -X POST https://localhost:{PORT}/widgets \
-H "Origin: https://attacker.example.com" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "name=test"
Substitua {PORT} pela porta HTTPS local da app. O 400 - Bad Request é observado porque o ponto final vincula o formulário, que faz cumprir o veredito registado. Um endpoint que não seja de formulário devolve a sua resposta normal porque nada lê a decisão. Sem o cabeçalho Origin, o mesmo pedido é permitido porque curl também não envia Sec-Fetch-Site e um pedido sem nenhum destes cabeçalhos é tratado como um cliente que não é um navegador.
O sistema antifalsificação baseado em tokens descrito no restante deste artigo é anterior a este middleware e continua disponível. Para a maioria das aplicações, a proteção automática já é suficiente por si só. Para orientações sobre quando manter o sistema baseado em tokens e como migrar, consulte Migrar de ASP.NET Core em .NET 10 para ASP.NET Core em .NET 11.
Antifalsificação no ASP.NET Core
Advertência
ASP.NET Core implementa antifalsificação usando ASP.NET Core Data Protection. A pilha de proteção de dados deve ser configurada para funcionar numa server farm. Para obter mais informações, consulte Configurando a proteção de dados.
O middleware antifalsificação é adicionado ao contêiner de injeção de dependência
Para obter mais informações, consulte Antifalsificação com APIs Mínimas.
O FormTagHelper injeta tokens antifalsificação em elementos de formulário HTML. A marcação a seguir em um arquivo Razor gera automaticamente tokens antifalsificação:
<form method="post">
<!-- ... -->
</form>
Da mesma forma, IHtmlHelper.BeginForm gera tokens antifalsificação por padrão se o método do formulário não for GET.
A geração automática de tokens antifalsificação para elementos de formulário HTML acontece quando a tag <form> contém o atributo method="post" e uma das seguintes opções é verdadeira:
- O atributo action está vazio (
action=""). - O atributo action não é fornecido (
<form method="post">).
A geração automática de tokens antifalsificação para elementos de formulário HTML pode ser desativada:
Desative explicitamente os tokens antifalsificação com o atributo
asp-antiforgery:<form method="post" asp-antiforgery="false"> <!-- ... --> </form>O elemento de formulário é excluído dos Auxiliares de Tag usando o símbolo de exclusão do Auxiliar de Tag !:
<!form method="post"> <!-- ... --> </!form>Remova o
FormTagHelperda visualização. OFormTagHelperpode ser removido de um modo de exibição adicionando a seguinte diretiva ao modo de exibição Razor:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Observação
Razor Páginas são automaticamente protegidas contra XSRF/CSRF. Para obter mais informações, consulte XSRF/CSRF e Razor Pages.
A abordagem mais comum para proteger contra ataques CSRF é usar o Synchronizer Token Pattern (STP). O STP é usado quando o usuário solicita uma página com dados de formulário:
- O servidor envia um token associado à identidade do usuário atual para o cliente.
- O cliente envia de volta o token para o servidor para verificação.
- Se o servidor receber um token que não corresponda à identidade do usuário autenticado, a solicitação será rejeitada.
O token é único e imprevisível. O token também pode ser usado para garantir o sequenciamento adequado de uma série de solicitações (por exemplo, garantindo a sequência de solicitação de: página 1 > página 2 > página 3). Todos os formulários nos modelos ASP.NET Core MVC e Razor Pages geram tokens antifalsificação. O seguinte par de exemplos de visualização gera tokens antifalsificação:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Adicione explicitamente um token antifalsificação a um elemento <form> sem usar Tag Helpers com o HTML helper @Html.AntiForgeryToken:
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Em cada um dos casos anteriores, o ASP.NET Core adiciona um campo de formulário oculto semelhante ao exemplo a seguir:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core inclui três filtros para trabalhar com tokens antifalsificação:
Antifalsificação com AddControllers
Chamar AddControllers não habilita tokens de antifalsificação. AddControllersWithViews deve ser chamado para ter suporte de token antifalsificação integrado.
Várias guias do navegador e o Padrão de Token do Sincronizador
Não é suportado ter várias abas abertas com acessos de diferentes utilizadores, ou abrir uma aba como anónimo.
Configurar o antifalsificação com o AntiforgeryOptions
Personalize AntiforgeryOptions no ficheiro Program da aplicação:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Defina as propriedades antifalsificação cookie usando as propriedades da classe CookieBuilder, conforme mostrado na tabela a seguir.
| Opção | Descrição |
|---|---|
| Cookie | Determina as configurações usadas para criar os cookies antifalsificação. |
| FormFieldName | O nome do campo de formulário oculto utilizado pelo sistema de proteção contra falsificação para renderizar tokens antifalsificação nas visualizações. |
| HeaderName | O nome do cabeçalho usado pelo sistema antifalsificação. Se null, o sistema considera apenas os dados do formulário. |
| SuppressXFrameOptionsHeader | Especifica se a geração do cabeçalho X-Frame-Options deve ser suprimida. Por padrão, o cabeçalho é gerado com um valor de "SAMEORIGIN". O padrão é false. |
Alguns navegadores não permitem que endpoints inseguros definam cookies com um sinalizador "seguro" ou substituam cookies cujo sinalizador "seguro" esteja definido (para obter mais informações, consulte Depreciar a modificação de cookies "seguros" de origens não seguras). Como misturar pontos de extremidade seguros e inseguros é um cenário comum em aplicações, o ASP.NET Core relaxa a restrição da política segura em alguns cookies, como o antiforjação cookie, ao definir o cookie de SecurePolicy como CookieSecurePolicy.None. Mesmo que um utilizador mal-intencionado roube um antifalsificação cookie, ele também deve roubar o token antifalsificação que normalmente é enviado por meio de um campo de formulário (mais comum) ou através de um cabeçalho de solicitação separado (menos comum), além de roubar a autenticação cookie. Os cookies relacionados com autenticação ou autorização utilizam uma política mais forte do que CookieSecurePolicy.Nonea .
Opcionalmente, pode proteger o token de antifalsificação cookie em ambientes nãoDevelopment seguros usando o protocolo Secure Sockets Layer (SSL), somente sobre HTTPS, com a seguinte definição de propriedades AntiforgeryOptions.Cookie no ficheiro da Program aplicação.
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddAntiforgery(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
}
Para obter mais informações, consulte CookieAuthenticationOptions.
Gere tokens antifalsificação com IAntiforgery
IAntiforgery fornece a API para configurar recursos antifalsificação.
IAntiforgery pode ser solicitado em Program.cs usando WebApplication.Services. O exemplo a seguir usa middleware da página inicial do aplicativo para gerar um token antifalsificação e enviá-lo na resposta como um cookie:
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
O exemplo anterior define um cookie chamado XSRF-TOKEN. O cliente pode ler essa cookie e fornecer seu valor como um cabeçalho anexado às solicitações AJAX. Por exemplo, o Angular inclui proteção XSRF integrada que, por padrão, lê um cookie chamado XSRF-TOKEN.
Exigir validação antifalsificação
O filtro de ação ValidateAntiForgeryToken pode ser aplicado a uma ação individual, a um controlador ou globalmente. As solicitações feitas para ações que têm esse filtro aplicado são bloqueadas, a menos que a solicitação inclua um token antifalsificação válido:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
O atributo ValidateAntiForgeryToken requer um token para solicitações para os métodos de ação que ele marca, incluindo solicitações HTTP GET. Se o atributo ValidateAntiForgeryToken for aplicado nos controladores do aplicativo, ele poderá ser substituído pelo atributo IgnoreAntiforgeryToken.
Valide automaticamente tokens antifalsificação apenas para métodos HTTP inseguros
Em vez de aplicar amplamente o atributo ValidateAntiForgeryToken e, em seguida, substituí-lo por atributos IgnoreAntiforgeryToken, o atributo AutoValidateAntiforgeryToken pode ser usado. Esse atributo funciona de forma idêntica ao atributo ValidateAntiForgeryToken, exceto que ele não requer tokens para solicitações feitas usando os seguintes métodos HTTP:
- OBTER
- CABEÇA
- OPÇÕES
- RASTREIO
Recomendamos o uso de AutoValidateAntiforgeryToken de forma ampla para cenários que não sejam de API. Esse atributo garante que as ações POST sejam protegidas por padrão. A alternativa é ignorar tokens de antifalsificação por padrão, a menos que ValidateAntiForgeryToken seja aplicado individualmente aos métodos de ação. É mais provável, neste cenário, que um método de ação POST seja deixado desprotegido por engano, deixando o aplicativo vulnerável a ataques CSRF. Todos os POSTs devem enviar o token antifalsificação.
As APIs não têm um mecanismo automático para enviar a parte nãocookie do token. A implementação provavelmente depende da implementação do código do cliente. Alguns exemplos são mostrados abaixo:
Exemplo de nível de classe:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Exemplo global:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Substituir atributos antifalsificação globais ou de controlador
O filtro IgnoreAntiforgeryToken é usado para eliminar a necessidade de um token antifalsificação para uma determinada ação (ou controlador). Quando aplicado, este filtro substitui os filtros ValidateAntiForgeryToken e AutoValidateAntiforgeryToken especificados a um nível superior (globalmente ou num controlador).
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Atualizar os tokens após a autenticação
Os tokens devem ser atualizados depois de o utilizador ser autenticado, redirecionando-o para uma vista ou página Razor Páginas.
JavaScript, AJAX e SPAs
Em aplicativos tradicionais baseados em HTML, os tokens antifalsificação são passados para o servidor usando campos de formulário ocultos. Em aplicativos e SPAs modernos baseados em JavaScript, muitas solicitações são feitas programaticamente. Essas solicitações AJAX podem usar outras técnicas, como cabeçalhos de solicitação ou cookies, para enviar o token.
Se os cookies forem usados para armazenar tokens de autenticação e autenticar solicitações de API no servidor, o CSRF é um problema potencial. Se o armazenamento local for usado para armazenar o token, a vulnerabilidade CSRF poderá ser atenuada porque os valores do armazenamento local não são enviados automaticamente para o servidor a cada solicitação. Usar o armazenamento local para armazenar o token antifalsificação no cliente e enviar o token como um cabeçalho de solicitação é uma abordagem recomendada.
Blazor
Para obter mais informações, consulte ASP.NET Core Blazor authentication and authorization.
JavaScript
Usando JavaScript com visualizações, o token pode ser criado usando um serviço de dentro da visualização. Injete o serviço de IAntiforgery na visualização e ligue para GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
O exemplo anterior usa JavaScript para ler o valor de campo oculto para o cabeçalho AJAX POST.
Esta abordagem elimina a necessidade de lidar diretamente com a configuração de cookies do servidor ou lê-los a partir do cliente. No entanto, quando não for possível injetar o serviço IAntiforgery, use JavaScript para acessar tokens em cookies:
- Tokens de acesso em uma solicitação adicional ao servidor, tipicamente
same-origin. - Use o conteúdo do cookiepara criar um cabeçalho com o valor do token.
Supondo que o script envie o token em um cabeçalho de solicitação chamado X-XSRF-TOKEN, configure o serviço antifalsificação para procurar o cabeçalho X-XSRF-TOKEN:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
O exemplo a seguir adiciona um ponto de extremidade protegido que grava o token de solicitação em um cookielegível por JavaScript:
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
O exemplo a seguir usa JavaScript para fazer uma solicitação AJAX para obter o token e fazer outra solicitação com o cabeçalho apropriado:
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Observação
Quando o token antifalsificação é fornecido no cabeçalho da solicitação e na carga útil do formulário, somente o token no cabeçalho é validado.
Antifalsificação com APIs mínimas
Chame AddAntiforgery e UseAntiforgery(IApplicationBuilder) para registar os serviços de antifalsificação na DI. Os tokens antifalsificação são usados para mitigar ataques de falsificação de solicitação entre sites.
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
app.MapGet("/", () => "Hello World!");
app.Run();
O middleware de antifalsificação de software:
- O não interrompe a execução do restante do pipeline de solicitação?
- Define o IAntiforgeryValidationFeature no HttpContext.Features da solicitação atual.
O token antifalsificação só é validado se:
- O ponto de extremidade contém metadados que implementam IAntiforgeryMetadata quando
RequiresValidation=trueocorre. - O método HTTP associado ao endpoint é um método HTTP relevante do tipo POST, PUT ou PATCH.
- A solicitação está associada a um ponto de extremidade válido.
O middleware antifalsificação não interrompe o pipeline de processamento de pedidos. O código do endpoint é sempre executado, mesmo que a validação do token falhe. Para observar o resultado da validação do token, resolva o IAntiforgeryValidationFeature de HttpContext.Features e inspecione a propriedade IsValid ou a propriedade Error para detalhes de falha. Esta abordagem é útil quando os endpoints requerem tratamento personalizado para validação antifalsificação falhada.
Nota: Quando ativado manualmente, o middleware antifalsificação deve ser executado após o middleware de autenticação e autorização para impedir a leitura de dados de formulário quando o usuário não é autenticado.
Por defeito, as APIs Mínimas que aceitam dados de formulário requerem validação de tokens antifalsificação e falham antes de executar o código da aplicação se a validação antifalsificação não for bem-sucedida.
Considere o seguinte método GenerateForm:
public static string GenerateForm(string action,
AntiforgeryTokenSet token, bool UseToken=true)
{
string tokenInput = "";
if (UseToken)
{
tokenInput = $@"<input name=""{token.FormFieldName}""
type=""hidden"" value=""{token.RequestToken}"" />";
}
return $@"
<html><body>
<form action=""{action}"" method=""POST"" enctype=""multipart/form-data"">
{tokenInput}
<input type=""text"" name=""name"" />
<input type=""date"" name=""dueDate"" />
<input type=""checkbox"" name=""isCompleted"" />
<input type=""submit"" />
</form>
</body></html>
";
}
O código anterior tem três argumentos, a ação, o token antifalsificação e um bool indicando se o token deve ser usado.
Considere o seguinte exemplo:
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
// Pass token
app.MapGet("/", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo", token), "text/html");
});
// Don't pass a token, fails
app.MapGet("/SkipToken", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo",token, false ), "text/html");
});
// Post to /todo2. DisableAntiforgery on that endpoint so no token needed.
app.MapGet("/DisableAntiforgery", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo2", token, false), "text/html");
});
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
app.Run();
class Todo
{
public required string Name { get; set; }
public bool IsCompleted { get; set; }
public DateTime DueDate { get; set; }
}
public static class MyHtml
{
public static string GenerateForm(string action,
AntiforgeryTokenSet token, bool UseToken=true)
{
string tokenInput = "";
if (UseToken)
{
tokenInput = $@"<input name=""{token.FormFieldName}""
type=""hidden"" value=""{token.RequestToken}"" />";
}
return $@"
<html><body>
<form action=""{action}"" method=""POST"" enctype=""multipart/form-data"">
{tokenInput}
<input type=""text"" name=""name"" />
<input type=""date"" name=""dueDate"" />
<input type=""checkbox"" name=""isCompleted"" />
<input type=""submit"" />
</form>
</body></html>
";
}
}
No código anterior, posta para:
-
/todoexige um token antifalsificação válido. -
/todo2não exige um token antifalsificação válido porque DisableAntiforgery é chamado.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
Advertência
A chamada .DisableAntiforgery() desativa a proteção contra ataques CSRF (Cross-Site Request Forgery) para o endpoint. Isto só deve ser usado quando um endpoint não está vulnerável a ataques CSRF, tais como:
- Endpoints que não podem ser chamados a partir de um navegador (por exemplo, APIs internas)
- Endpoints protegidos com autenticação não baseada em cookie (por exemplo, tokens bearer ou chaves de API)
- Endpoints internos ou de infraestrutura que não dependem de cookies de utilizador
Não desative a validação antifalsificação para endpoints acessíveis ao navegador que dependem de cookies para autenticação ou que processam dados de formulários submetidos pelo utilizador, pois isso expõe a sua aplicação a ataques CSRF.
Um POST para:
-
/tododo formulário gerado pelo endpoint/é bem-sucedido porque o token antifalsificação é válido. -
/tododo formulário gerado pelo/SkipTokenfalha porque o antifalsificação não está incluído. -
/todo2do formulário gerado pelo ponto de extremidade/DisableAntiforgerytem sucesso porque a proteção contra falsificação não é necessária.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
Quando um formulário é enviado sem um token antifalsificação válido:
- No
Developmentambiente, é lançada uma exceção. - No
Productionambiente, uma mensagem é registada.
Limitações do método HTTP e da interação HttpMethodOverrideMiddleware
Para o caminho de antifalsificação baseado em middleware, AntiforgeryMiddleware e UseAntiforgery() validam os tokens de antifalsificação apenas para pedidos HTTP do tipo POST, PUT e PATCH. Outros métodos HTTP, como o DELETE, não são validados automaticamente.
Para validar tokens de proteção antifalsificação para outros métodos HTTP, resolva IAntiforgery através da DI e chame ValidateRequestAsync ou IsRequestValidAsync explicitamente:
app.MapDelete("/item/{id}", async (int id, IAntiforgery antiforgery, HttpContext context) =>
{
await antiforgery.ValidateRequestAsync(context);
// Process the DELETE request
});
Advertência
Quando HttpMethodOverrideMiddleware está configurado com FormFieldName (modo de campo de formulário) e colocado antes de AntiforgeryMiddleware, um pedido POST pode ser substituído por DELETE (ou outro método não validado). Como AntiforgeryMiddleware valida apenas POST, PUT e PATCH, o pedido substituído contorna a validação anti-falsificação.
Para proteger estes endpoints:
- Prefira colocar
HttpMethodOverrideMiddlewareapós a validação antifalsificação quando o seu pipeline o permitir. - Evite sobrescrições de campos de formulário para endpoints que dependam da validação antifalsificação.
- Se a substituição do campo de formulário tiver de ser executada primeiro, valide explicitamente o token anti-falsificação usando
IAntiforgery.ValidateRequestAsync.
Para detalhes de configuração, consulte o middleware ASP.NET Core.
Cookies de autenticação e antifalsificação do Windows
Ao usar a Autenticação do Windows, os pontos de extremidade da aplicação devem ser protegidos contra ataques CSRF da mesma maneira que são protegidos os cookies. O navegador envia implicitamente o contexto de autenticação para o servidor e os endpoints precisam ser protegidos contra ataques CSRF.
Estender a antifalsificação
O tipo IAntiforgeryAdditionalDataProvider permite que os desenvolvedores estendam o comportamento do sistema anti-CSRF ao incluir dados adicionais em cada token. O método GetAdditionalData é chamado cada vez que um token de campo é gerado, e o valor de retorno é incorporado no token gerado. Um implementador pode retornar um carimbo de data/hora, um nonce ou qualquer outro valor e, em seguida, chamar ValidateAdditionalData para validar esses dados quando o token for validado. O nome de usuário do cliente já está incorporado nos tokens gerados, portanto, não há necessidade de incluir essas informações. Se um token incluir dados suplementares, mas nenhum IAntiForgeryAdditionalDataProvider estiver configurado, os dados suplementares não serão validados.
Recursos adicionais
A falsificação de solicitação entre sites (também conhecida como XSRF ou CSRF) é um ataque contra aplicativos hospedados na Web pelo qual um aplicativo Web mal-intencionado pode influenciar a interação entre um navegador cliente e um aplicativo Web que confia nesse navegador. Esses ataques são possíveis porque os navegadores da Web enviam alguns tipos de tokens de autenticação automaticamente a cada solicitação para um site. Essa forma de exploração também é conhecida como ataque de um clique ou sequestro de sessão porque o ataque aproveita a sessão previamente autenticada do utilizador.
Um exemplo de um ataque CSRF:
Um utilizador entra em
www.good-banking-site.example.comusando a autenticação por formulários. O servidor autentica o usuário e emite uma resposta que inclui uma autenticação cookie. O site é vulnerável a ataques porque confia em qualquer solicitação recebida com uma autenticação válida cookie.O utilizador visita um site malicioso,
www.bad-crook-site.example.com.O site mal-intencionado,
www.bad-crook-site.example.com, contém um formulário HTML semelhante ao exemplo a seguir:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>Observe que o
actiondo formulário envia informações para o site vulnerável, não para o site malicioso. Esta é a parte "cross-site" da CSRF.O usuário seleciona o botão enviar. O navegador faz a solicitação e inclui automaticamente a autenticação cookie para o domínio solicitado,
www.good-banking-site.example.com.A solicitação é executada no servidor
www.good-banking-site.example.comcom o contexto de autenticação do usuário e pode executar qualquer ação que um usuário autenticado tenha permissão para executar.
Além do cenário em que o usuário seleciona o botão para enviar o formulário, o site mal-intencionado pode:
- Execute um script que envia automaticamente o formulário.
- Envie o envio do formulário como uma solicitação AJAX.
- Oculte o formulário usando CSS.
Esses cenários alternativos não exigem nenhuma ação ou entrada do usuário além de visitar inicialmente o site mal-intencionado.
O uso de HTTPS não impede um ataque CSRF. O site mal-intencionado pode enviar uma solicitação https://www.good-banking-site.example.com/ tão facilmente quanto pode enviar uma solicitação insegura.
Alguns ataques têm como alvo endpoints que respondem a solicitações GET, caso em que uma etiqueta de imagem pode ser usada para executar a ação. Esta forma de ataque é comum em sites de fóruns que permitem imagens, mas bloqueiam JavaScript. Os aplicativos que mudam de estado em solicitações GET, onde variáveis ou recursos são alterados, são vulneráveis a ataques mal-intencionados. As solicitações GET que mudam de estado são inseguras. Uma prática recomendada é nunca alterar o estado em uma solicitação GET.
Os ataques CSRF são possíveis contra aplicativos da Web que usam cookies para autenticação porque:
- Os navegadores armazenam cookies emitidos por um aplicativo da Web.
- Os cookies armazenados incluem cookies de sessão para utilizadores autenticados.
- Os navegadores enviam todos os cookies associados a um domínio para o aplicativo Web a cada solicitação, independentemente de como a solicitação para o aplicativo foi gerada dentro do navegador.
No entanto, os ataques CSRF não se limitam a explorar cookies. Por exemplo, as autenticações Basic e Digest também são vulneráveis. Depois que um usuário entra com autenticação Básica ou Digest, o navegador envia automaticamente as credenciais até que a sessão termine.
Neste contexto, sessão refere-se à sessão do lado do cliente durante a qual o usuário é autenticado. Não está relacionado com sessões do lado do servidor nem com middleware de sessões ASP.NET Core.
Os usuários podem se proteger contra vulnerabilidades CSRF tomando precauções:
- Saia dos aplicativos Web quando terminar de usá-los.
- Limpe os cookies do navegador periodicamente.
No entanto, as vulnerabilidades CSRF são fundamentalmente um problema com o aplicativo Web, não com o usuário final.
Fundamentos de autenticação
A autenticação baseada em Cookieé uma forma popular de autenticação. Os sistemas de autenticação baseados em tokens estão crescendo em popularidade, especialmente para aplicativos de página única (SPAs).
Autenticação baseada em Cookie
Quando um usuário se autentica usando seu nome de usuário e senha, ele recebe um token, contendo um tíquete de autenticação que pode ser usado para autenticação e autorização. O token é armazenado como um cookie que é enviado a cada solicitação feita pelo cliente. A geração e a validação deste cookie são efetuadas pelo cookie middleware de autenticação. O middleware serializa uma entidade de usuário em um cookiecriptografado. Em solicitações subsequentes, o middleware valida o cookie, recria o principal e atribui o principal à propriedade HttpContext.User.
Autenticação baseada em tokens
Quando um usuário é autenticado, ele recebe um token (não um token antifalsificação). O token contém informações do usuário na forma de declarações ou um token de referência que aponta o aplicativo para o estado do usuário mantido no aplicativo. Quando um usuário tenta acessar um recurso que requer autenticação, o token é enviado para o aplicativo com um cabeçalho de autorização extra na forma de um token de portador. Essa abordagem torna a aplicação sem estado. Em cada solicitação subsequente, o token é passado na solicitação de validação do lado do servidor. Este token não é criptografado; é codificado. No servidor, o token é decodificado para acessar suas informações. Para enviar o token em solicitações subsequentes, armazene-o no armazenamento local do navegador. Colocar um token no armazenamento local do navegador e recuperá-lo e usá-lo como um token de portador fornece proteção contra ataques CSRF. No entanto, se o aplicativo estiver vulnerável à injeção de script via XSS ou um arquivo javascript externo comprometido, um ciberinvasor pode recuperar qualquer valor do armazenamento local e enviá-lo para si mesmo. ASP.NET Core codifica todas as saídas do lado do servidor de variáveis por padrão, reduzindo o risco de XSS. Se substituir este comportamento usando Html.Raw ou códigos personalizados com entradas não confiáveis, poderá aumentar o risco de XSS.
Não se preocupe com a vulnerabilidade CSRF se o token estiver armazenado no armazenamento local do navegador. CSRF é uma preocupação quando o token é armazenado num cookie. Para obter mais informações, consulte o problema da GitHub , onde o exemplo de código SPA adiciona dois cookies.
Vários aplicativos hospedados em um domínio
Os ambientes de hospedagem compartilhada são vulneráveis a sequestro de sessão, CSRF de login e outros ataques.
Embora example1.contoso.net e example2.contoso.net sejam hosts diferentes, há uma relação de confiança implícita entre hosts sob o domínio *.contoso.net. Essa relação de confiança implícita permite que hosts potencialmente não confiáveis afetem os cookies uns dos outros (as políticas de mesma origem que regem as solicitações AJAX não se aplicam necessariamente aos cookies HTTP).
Os ataques que exploram cookies confiáveis entre aplicativos hospedados no mesmo domínio podem ser evitados não compartilhando domínios. Quando cada aplicativo é hospedado em seu próprio domínio, não há nenhuma relação de confiança implícita cookie para explorar.
Antifalsificação no ASP.NET Core
Advertência
ASP.NET Core implementa antifalsificação usando ASP.NET Core Data Protection. A pilha de proteção de dados deve ser configurada para funcionar numa server farm. Para obter mais informações, consulte Configurando a proteção de dados.
O middleware antifalsificação é adicionado ao contêiner de injeção de dependência
O FormTagHelper injeta tokens antifalsificação em elementos de formulário HTML. A marcação a seguir em um arquivo Razor gera automaticamente tokens antifalsificação:
<form method="post">
<!-- ... -->
</form>
Da mesma forma, IHtmlHelper.BeginForm gera tokens antifalsificação por padrão se o método do formulário não for GET.
A geração automática de tokens antifalsificação para elementos de formulário HTML acontece quando a tag <form> contém o atributo method="post" e uma das seguintes opções é verdadeira:
- O atributo action está vazio (
action=""). - O atributo action não é fornecido (
<form method="post">).
A geração automática de tokens antifalsificação para elementos de formulário HTML pode ser desativada:
Desative explicitamente os tokens antifalsificação com o atributo
asp-antiforgery:<form method="post" asp-antiforgery="false"> <!-- ... --> </form>O elemento de formulário é excluído dos Auxiliares de Tag usando o símbolo de exclusão do Auxiliar de Tag !:
<!form method="post"> <!-- ... --> </!form>Remova o
FormTagHelperda visualização. OFormTagHelperpode ser removido de um modo de exibição adicionando a seguinte diretiva ao modo de exibição Razor:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Observação
Razor Páginas são automaticamente protegidas contra XSRF/CSRF. Para obter mais informações, consulte XSRF/CSRF e Razor Pages.
A abordagem mais comum para se defender contra ataques CSRF é usar o Synchronizer Token Pattern (STP). O STP é usado quando o usuário solicita uma página com dados de formulário:
- O servidor envia um token associado à identidade do usuário atual para o cliente.
- O cliente envia de volta o token para o servidor para verificação.
- Se o servidor receber um token que não corresponda à identidade do usuário autenticado, a solicitação será rejeitada.
O token é único e imprevisível. O token também pode ser usado para garantir o sequenciamento adequado de uma série de solicitações (por exemplo, garantindo a sequência de solicitação de: página 1 > página 2 > página 3). Todos os formulários nos modelos ASP.NET Core MVC e Razor Pages geram tokens antifalsificação. O seguinte par de exemplos de visualização gera tokens antifalsificação:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Adicione explicitamente um token antifalsificação a um elemento <form> sem usar Tag Helpers com o HTML helper @Html.AntiForgeryToken:
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Em cada um dos casos anteriores, o ASP.NET Core adiciona um campo de formulário oculto semelhante ao exemplo a seguir:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core inclui três filtros para trabalhar com tokens antifalsificação:
Antifalsificação com AddControllers
Chamar AddControllers não habilita tokens de antifalsificação. AddControllersWithViews deve ser chamado para ter suporte de token antifalsificação integrado.
Várias guias do navegador e o Padrão de Token do Sincronizador
Com o Synchronizer Token Pattern, apenas a página carregada mais recentemente contém um token antifalsificação válido. O uso de múltiplas guias pode ser problemático. Por exemplo, se um usuário abrir várias guias:
- Apenas o separador carregado mais recentemente contém um token antifalsificação válido.
- Solicitações originadas em guias carregadas anteriormente falham com um erro:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Considere padrões alternativos de proteção CSRF se isso representar um problema.
Configurar o antifalsificação com o AntiforgeryOptions
Personalize AntiforgeryOptions no ficheiro Program da aplicação:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Defina as propriedades antifalsificação cookie usando as propriedades da classe CookieBuilder, conforme mostrado na tabela a seguir.
| Opção | Descrição |
|---|---|
| Cookie | Determina as configurações usadas para criar os cookies antifalsificação. |
| FormFieldName | O nome do campo de formulário oculto utilizado pelo sistema de proteção contra falsificação para renderizar tokens antifalsificação nas visualizações. |
| HeaderName | O nome do cabeçalho usado pelo sistema antifalsificação. Se null, o sistema considera apenas os dados do formulário. |
| SuppressXFrameOptionsHeader | Especifica se a geração do cabeçalho X-Frame-Options deve ser suprimida. Por padrão, o cabeçalho é gerado com um valor de "SAMEORIGIN". O padrão é false. |
Alguns navegadores não permitem que endpoints inseguros definam cookies com um sinalizador "seguro" ou substituam cookies cujo sinalizador "seguro" esteja definido (para obter mais informações, consulte Depreciar a modificação de cookies "seguros" de origens não seguras). Como misturar pontos de extremidade seguros e inseguros é um cenário comum em aplicações, o ASP.NET Core relaxa a restrição da política segura em alguns cookies, como o antiforjação cookie, ao definir o cookie de SecurePolicy como CookieSecurePolicy.None. Mesmo que um utilizador mal-intencionado roube um antifalsificação cookie, ele também deve roubar o token antifalsificação que normalmente é enviado por meio de um campo de formulário (mais comum) ou através de um cabeçalho de solicitação separado (menos comum), além de roubar a autenticação cookie. Os cookies relacionados com autenticação ou autorização utilizam uma política mais forte do que CookieSecurePolicy.Nonea .
Opcionalmente, pode proteger o token de antifalsificação cookie em ambientes nãoDevelopment seguros usando o protocolo Secure Sockets Layer (SSL), somente sobre HTTPS, com a seguinte definição de propriedades AntiforgeryOptions.Cookie no ficheiro da Program aplicação.
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddAntiforgery(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
}
Para obter mais informações, consulte CookieAuthenticationOptions.
Gere tokens antifalsificação com IAntiforgery
IAntiforgery fornece a API para configurar recursos antifalsificação.
IAntiforgery pode ser solicitado em Program.cs usando WebApplication.Services. O exemplo a seguir usa middleware da página inicial do aplicativo para gerar um token antifalsificação e enviá-lo na resposta como um cookie:
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
O exemplo anterior define um cookie chamado XSRF-TOKEN. O cliente pode ler essa cookie e fornecer seu valor como um cabeçalho anexado às solicitações AJAX. Por exemplo, o Angular inclui proteção XSRF integrada que, por padrão, lê um cookie chamado XSRF-TOKEN.
Exigir validação antifalsificação
O filtro de ação ValidateAntiForgeryToken pode ser aplicado a uma ação individual, a um controlador ou globalmente. As solicitações feitas para ações que têm esse filtro aplicado são bloqueadas, a menos que a solicitação inclua um token antifalsificação válido:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
O atributo ValidateAntiForgeryToken requer um token para solicitações para os métodos de ação que ele marca, incluindo solicitações HTTP GET. Se o atributo ValidateAntiForgeryToken for aplicado nos controladores do aplicativo, ele poderá ser substituído pelo atributo IgnoreAntiforgeryToken.
Valide automaticamente tokens antifalsificação apenas para métodos HTTP inseguros
Em vez de aplicar amplamente o atributo ValidateAntiForgeryToken e, em seguida, substituí-lo por atributos IgnoreAntiforgeryToken, o atributo AutoValidateAntiforgeryToken pode ser usado. Esse atributo funciona de forma idêntica ao atributo ValidateAntiForgeryToken, exceto que ele não requer tokens para solicitações feitas usando os seguintes métodos HTTP:
- OBTER
- CABEÇA
- OPÇÕES
- RASTREIO
Recomendamos o uso de AutoValidateAntiforgeryToken de forma ampla para cenários que não sejam de API. Esse atributo garante que as ações POST sejam protegidas por padrão. A alternativa é ignorar tokens de antifalsificação por padrão, a menos que ValidateAntiForgeryToken seja aplicado individualmente aos métodos de ação. É mais provável, neste cenário, que um método de ação POST seja deixado desprotegido por engano, deixando o aplicativo vulnerável a ataques CSRF. Todos os POSTs devem enviar o token antifalsificação.
As APIs não têm um mecanismo automático para enviar a parte nãocookie do token. A implementação provavelmente depende da implementação do código do cliente. Alguns exemplos são mostrados abaixo:
Exemplo de nível de classe:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Exemplo global:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Substituir atributos antifalsificação globais ou de controlador
O filtro IgnoreAntiforgeryToken é usado para eliminar a necessidade de um token antifalsificação para uma determinada ação (ou controlador). Quando aplicado, este filtro substitui os filtros ValidateAntiForgeryToken e AutoValidateAntiforgeryToken especificados a um nível superior (globalmente ou num controlador).
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Atualizar os tokens após a autenticação
Os tokens devem ser atualizados depois de o utilizador ser autenticado, redirecionando-o para uma vista ou página Razor Páginas.
JavaScript, AJAX e SPAs
Em aplicativos tradicionais baseados em HTML, os tokens antifalsificação são passados para o servidor usando campos de formulário ocultos. Em aplicativos e SPAs modernos baseados em JavaScript, muitas solicitações são feitas programaticamente. Essas solicitações AJAX podem usar outras técnicas (como cabeçalhos de solicitação ou cookies) para enviar o token.
Se os cookies forem usados para armazenar tokens de autenticação e autenticar solicitações de API no servidor, o CSRF é um problema potencial. Se o armazenamento local for usado para armazenar o token, a vulnerabilidade CSRF poderá ser atenuada porque os valores do armazenamento local não são enviados automaticamente para o servidor a cada solicitação. Usar o armazenamento local para armazenar o token antifalsificação no cliente e enviar o token como um cabeçalho de solicitação é uma abordagem recomendada.
JavaScript
Usando JavaScript com visualizações, o token pode ser criado usando um serviço de dentro da visualização. Injete o serviço de IAntiforgery na visualização e ligue para GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
O exemplo anterior usa JavaScript para ler o valor de campo oculto para o cabeçalho AJAX POST.
Esta abordagem elimina a necessidade de lidar diretamente com a configuração de cookies do servidor ou lê-los a partir do cliente. No entanto, quando não for possível injetar o serviço IAntiforgery, use JavaScript para acessar tokens em cookies:
- Tokens de acesso em uma solicitação adicional ao servidor, tipicamente
same-origin. - Use o conteúdo do cookiepara criar um cabeçalho com o valor do token.
Supondo que o script envie o token em um cabeçalho de solicitação chamado X-XSRF-TOKEN, configure o serviço antifalsificação para procurar o cabeçalho X-XSRF-TOKEN:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
O exemplo a seguir adiciona um ponto de extremidade protegido que grava o token de solicitação em um cookielegível por JavaScript:
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
O exemplo a seguir usa JavaScript para fazer uma solicitação AJAX para obter o token e fazer outra solicitação com o cabeçalho apropriado:
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Observação
Quando o token antifalsificação é fornecido no cabeçalho da solicitação e na carga útil do formulário, somente o token no cabeçalho é validado.
Antifalsificação com APIs mínimas
Minimal APIs não suportam o uso dos filtros incluídos (ValidateAntiForgeryToken, AutoValidateAntiforgeryToken, IgnoreAntiforgeryToken), no entanto, IAntiforgery fornece as APIs necessárias para validar uma solicitação.
O exemplo a seguir cria um filtro que valida o token antifalsificação:
internal static class AntiForgeryExtensions
{
public static TBuilder ValidateAntiforgery<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder
{
return builder.AddEndpointFilter(routeHandlerFilter: async (context, next) =>
{
try
{
var antiForgeryService = context.HttpContext.RequestServices.GetRequiredService<IAntiforgery>();
await antiForgeryService.ValidateRequestAsync(context.HttpContext);
}
catch (AntiforgeryValidationException)
{
return Results.BadRequest("Antiforgery token validation failed.");
}
return await next(context);
});
}
}
O filtro pode então ser aplicado a um ponto de extremidade:
app.MapPost("api/upload", (IFormFile name) => Results.Accepted())
.RequireAuthorization()
.ValidateAntiforgery();
Cookies de autenticação e antifalsificação do Windows
Ao usar a Autenticação do Windows, os pontos de extremidade da aplicação devem ser protegidos contra ataques CSRF da mesma maneira que são protegidos os cookies. O navegador envia implicitamente o contexto de autenticação para o servidor e os endpoints precisam ser protegidos contra ataques CSRF.
Estender a antifalsificação
O tipo IAntiforgeryAdditionalDataProvider permite que os desenvolvedores estendam o comportamento do sistema anti-CSRF ao incluir dados adicionais em cada token. O método GetAdditionalData é chamado cada vez que um token de campo é gerado, e o valor de retorno é incorporado no token gerado. Um implementador pode retornar um carimbo de data/hora, um nonce ou qualquer outro valor e, em seguida, chamar ValidateAdditionalData para validar esses dados quando o token for validado. O nome de usuário do cliente já está incorporado nos tokens gerados, portanto, não há necessidade de incluir essas informações. Se um token incluir dados suplementares, mas nenhum IAntiForgeryAdditionalDataProvider estiver configurado, os dados suplementares não serão validados.
Recursos adicionais
A falsificação de solicitação entre sites (também conhecida como XSRF ou CSRF) é um ataque contra aplicativos hospedados na Web pelo qual um aplicativo Web mal-intencionado pode influenciar a interação entre um navegador cliente e um aplicativo Web que confia nesse navegador. Esses ataques são possíveis porque os navegadores da Web enviam alguns tipos de tokens de autenticação automaticamente a cada solicitação para um site. Essa forma de exploração também é conhecida como ataque de um clique ou sequestro de sessão porque o ataque aproveita a sessão previamente autenticada do utilizador.
Um exemplo de um ataque CSRF:
Um utilizador entra em
www.good-banking-site.example.comusando a autenticação por formulários. O servidor autentica o usuário e emite uma resposta que inclui uma autenticação cookie. O site é vulnerável a ataques porque confia em qualquer solicitação recebida com uma autenticação válida cookie.O utilizador visita um site malicioso,
www.bad-crook-site.example.com.O site mal-intencionado,
www.bad-crook-site.example.com, contém um formulário HTML semelhante ao exemplo a seguir:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>Observe que o
actiondo formulário envia informações para o site vulnerável, não para o site malicioso. Esta é a parte "cross-site" da CSRF.O usuário seleciona o botão enviar. O navegador faz a solicitação e inclui automaticamente a autenticação cookie para o domínio solicitado,
www.good-banking-site.example.com.A solicitação é executada no servidor
www.good-banking-site.example.comcom o contexto de autenticação do usuário e pode executar qualquer ação que um usuário autenticado tenha permissão para executar.
Além do cenário em que o usuário seleciona o botão para enviar o formulário, o site mal-intencionado pode:
- Execute um script que envia automaticamente o formulário.
- Envie o envio do formulário como uma solicitação AJAX.
- Oculte o formulário usando CSS.
Esses cenários alternativos não exigem nenhuma ação ou entrada do usuário além de visitar inicialmente o site mal-intencionado.
O uso de HTTPS não impede um ataque CSRF. O site mal-intencionado pode enviar uma solicitação https://www.good-banking-site.example.com/ tão facilmente quanto pode enviar uma solicitação insegura.
Alguns ataques têm como alvo endpoints que respondem a solicitações GET, caso em que uma etiqueta de imagem pode ser usada para executar a ação. Esta forma de ataque é comum em sites de fóruns que permitem imagens, mas bloqueiam JavaScript. Os aplicativos que mudam de estado em solicitações GET, onde variáveis ou recursos são alterados, são vulneráveis a ataques mal-intencionados. As solicitações GET que mudam de estado são inseguras. Uma prática recomendada é nunca alterar o estado em uma solicitação GET.
Os ataques CSRF são possíveis contra aplicativos da Web que usam cookies para autenticação porque:
- Os navegadores armazenam cookies emitidos por um aplicativo da Web.
- Os cookies armazenados incluem cookies de sessão para utilizadores autenticados.
- Os navegadores enviam todos os cookies associados a um domínio para o aplicativo Web a cada solicitação, independentemente de como a solicitação para o aplicativo foi gerada dentro do navegador.
No entanto, os ataques CSRF não se limitam a explorar cookies. Por exemplo, as autenticações Basic e Digest também são vulneráveis. Depois que um usuário entra com autenticação Básica ou Digest, o navegador envia automaticamente as credenciais até que a sessão termine.
Neste contexto, sessão refere-se à sessão do lado do cliente durante a qual o usuário é autenticado. Não está relacionado com sessões do lado do servidor nem com middleware de sessões ASP.NET Core.
Os usuários podem se proteger contra vulnerabilidades CSRF tomando precauções:
- Saia dos aplicativos Web quando terminar de usá-los.
- Limpe os cookies do navegador periodicamente.
No entanto, as vulnerabilidades CSRF são fundamentalmente um problema com o aplicativo Web, não com o usuário final.
Fundamentos de autenticação
A autenticação baseada em Cookieé uma forma popular de autenticação. Os sistemas de autenticação baseados em tokens estão crescendo em popularidade, especialmente para aplicativos de página única (SPAs).
Autenticação baseada em Cookie
Quando um usuário se autentica usando seu nome de usuário e senha, ele recebe um token, contendo um tíquete de autenticação que pode ser usado para autenticação e autorização. O token é armazenado como um cookie que é enviado a cada solicitação feita pelo cliente. A geração e a validação deste cookie é realizada pelo cookie middleware de autenticação. O middleware serializa uma entidade de usuário em um cookiecriptografado. Em solicitações subsequentes, o middleware valida o cookie, recria o principal e atribui o principal à propriedade HttpContext.User.
Autenticação baseada em tokens
Quando um usuário é autenticado, ele recebe um token (não um token antifalsificação). O token contém informações do usuário na forma de declarações ou um token de referência que aponta o aplicativo para o estado do usuário mantido no aplicativo. Quando um usuário tenta acessar um recurso que requer autenticação, o token é enviado para o aplicativo com um cabeçalho de autorização extra na forma de um token de portador. Essa abordagem torna a aplicação sem estado. Em cada solicitação subsequente, o token é passado na solicitação de validação do lado do servidor. Este token não é criptografado; é codificado. No servidor, o token é decodificado para acessar suas informações. Para enviar o token em solicitações subsequentes, armazene-o no armazenamento local do navegador. Não se preocupe com a vulnerabilidade CSRF se o token estiver armazenado no armazenamento local do navegador. CSRF é uma preocupação quando o token é armazenado num cookie. Para obter mais informações, consulte o problema da GitHub , onde o exemplo de código SPA adiciona dois cookies.
Vários aplicativos hospedados em um domínio
Os ambientes de hospedagem compartilhada são vulneráveis a sequestro de sessão, CSRF de login e outros ataques.
Embora example1.contoso.net e example2.contoso.net sejam hosts diferentes, há uma relação de confiança implícita entre hosts sob o domínio *.contoso.net. Essa relação de confiança implícita permite que hosts potencialmente não confiáveis afetem os cookies uns dos outros (as políticas de mesma origem que regem as solicitações AJAX não se aplicam necessariamente aos cookies HTTP).
Os ataques que exploram cookies confiáveis entre aplicativos hospedados no mesmo domínio podem ser evitados não compartilhando domínios. Quando cada aplicativo é hospedado em seu próprio domínio, não há nenhuma relação de confiança implícita cookie para explorar.
Antifalsificação no ASP.NET Core
Advertência
ASP.NET Core implementa antifalsificação usando ASP.NET Core Data Protection. A pilha de proteção de dados deve ser configurada para funcionar numa server farm. Para obter mais informações, consulte Configurando a proteção de dados.
O middleware antifalsificação é adicionado ao contêiner de injeção de dependência
O FormTagHelper injeta tokens antifalsificação em elementos de formulário HTML. A marcação a seguir em um arquivo Razor gera automaticamente tokens antifalsificação:
<form method="post">
<!-- ... -->
</form>
Da mesma forma, IHtmlHelper.BeginForm gera tokens antifalsificação por padrão se o método do formulário não for GET.
A geração automática de tokens antifalsificação para elementos de formulário HTML acontece quando a tag <form> contém o atributo method="post" e uma das seguintes opções é verdadeira:
- O atributo action está vazio (
action=""). - O atributo action não é fornecido (
<form method="post">).
A geração automática de tokens antifalsificação para elementos de formulário HTML pode ser desativada:
Desative explicitamente os tokens antifalsificação com o atributo
asp-antiforgery:<form method="post" asp-antiforgery="false"> <!-- ... --> </form>O elemento de formulário é excluído dos Auxiliares de Tag usando o símbolo de exclusão do Auxiliar de Tag !:
<!form method="post"> <!-- ... --> </!form>Remova o
FormTagHelperda visualização. OFormTagHelperpode ser removido de um modo de exibição adicionando a seguinte diretiva ao modo de exibição Razor:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Observação
Razor Páginas são automaticamente protegidas contra XSRF/CSRF. Para obter mais informações, consulte XSRF/CSRF e Razor Pages.
A abordagem mais comum para se defender contra ataques CSRF é usar o Synchronizer Token Pattern (STP). O STP é usado quando o usuário solicita uma página com dados de formulário:
- O servidor envia um token associado à identidade do usuário atual para o cliente.
- O cliente envia de volta o token para o servidor para verificação.
- Se o servidor receber um token que não corresponda à identidade do usuário autenticado, a solicitação será rejeitada.
O token é único e imprevisível. O token também pode ser usado para garantir o sequenciamento adequado de uma série de solicitações (por exemplo, garantindo a sequência de solicitação de: página 1 > página 2 > página 3). Todos os formulários nos modelos ASP.NET Core MVC e Razor Pages geram tokens antifalsificação. O seguinte par de exemplos de visualização gera tokens antifalsificação:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Adicione explicitamente um token antifalsificação a um elemento <form> sem usar Tag Helpers com o HTML helper @Html.AntiForgeryToken:
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Em cada um dos casos anteriores, o ASP.NET Core adiciona um campo de formulário oculto semelhante ao exemplo a seguir:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core inclui três filtros para trabalhar com tokens antifalsificação:
Antifalsificação com AddControllers
Chamar AddControllers não habilita tokens de antifalsificação. AddControllersWithViews deve ser chamado para ter suporte de token antifalsificação integrado.
Várias guias do navegador e o Padrão de Token do Sincronizador
Com o Synchronizer Token Pattern, apenas a página carregada mais recentemente contém um token antifalsificação válido. O uso de múltiplas guias pode ser problemático. Por exemplo, se um usuário abrir várias guias:
- Apenas o separador carregado mais recentemente contém um token antifalsificação válido.
- Solicitações originadas em guias carregadas anteriormente falham com um erro:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Considere padrões alternativos de proteção CSRF se isso representar um problema.
Configurar o antifalsificação com o AntiforgeryOptions
Personalize AntiforgeryOptions no ficheiro Program da aplicação:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Defina as propriedades antifalsificação cookie usando as propriedades da classe CookieBuilder, conforme mostrado na tabela a seguir.
| Opção | Descrição |
|---|---|
| Cookie | Determina as configurações usadas para criar os cookies antifalsificação. |
| FormFieldName | O nome do campo de formulário oculto utilizado pelo sistema de proteção contra falsificação para renderizar tokens antifalsificação nas visualizações. |
| HeaderName | O nome do cabeçalho usado pelo sistema antifalsificação. Se null, o sistema considera apenas os dados do formulário. |
| SuppressXFrameOptionsHeader | Especifica se a geração do cabeçalho X-Frame-Options deve ser suprimida. Por padrão, o cabeçalho é gerado com um valor de "SAMEORIGIN". O padrão é false. |
Alguns navegadores não permitem que endpoints inseguros definam cookies com um sinalizador "seguro" ou substituam cookies cujo sinalizador "seguro" esteja definido (para obter mais informações, consulte Depreciar a modificação de cookies "seguros" de origens não seguras). Como misturar pontos de extremidade seguros e inseguros é um cenário comum em aplicações, o ASP.NET Core relaxa a restrição da política segura em alguns cookies, como o antiforjação cookie, ao definir o cookie de SecurePolicy como CookieSecurePolicy.None. Mesmo que um utilizador mal-intencionado roube um antifalsificação cookie, ele também deve roubar o token antifalsificação que normalmente é enviado por meio de um campo de formulário (mais comum) ou através de um cabeçalho de solicitação separado (menos comum), além de roubar a autenticação cookie. Os cookies relacionados com autenticação ou autorização utilizam uma política mais forte do que CookieSecurePolicy.Nonea .
Opcionalmente, pode proteger o token de antifalsificação cookie em ambientes nãoDevelopment seguros usando o protocolo Secure Sockets Layer (SSL), somente sobre HTTPS, com a seguinte definição de propriedades AntiforgeryOptions.Cookie no ficheiro da Program aplicação.
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddAntiforgery(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
}
Para obter mais informações, consulte CookieAuthenticationOptions.
Gere tokens antifalsificação com IAntiforgery
IAntiforgery fornece a API para configurar recursos antifalsificação.
IAntiforgery pode ser solicitado em Program.cs usando WebApplication.Services. O exemplo a seguir usa middleware da página inicial do aplicativo para gerar um token antifalsificação e enviá-lo na resposta como um cookie:
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
O exemplo anterior define um cookie chamado XSRF-TOKEN. O cliente pode ler essa cookie e fornecer seu valor como um cabeçalho anexado às solicitações AJAX. Por exemplo, o Angular inclui proteção XSRF integrada que, por padrão, lê um cookie chamado XSRF-TOKEN.
Exigir validação antifalsificação
O filtro de ação ValidateAntiForgeryToken pode ser aplicado a uma ação individual, a um controlador ou globalmente. As solicitações feitas para ações que têm esse filtro aplicado são bloqueadas, a menos que a solicitação inclua um token antifalsificação válido:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
O atributo ValidateAntiForgeryToken requer um token para solicitações para os métodos de ação que ele marca, incluindo solicitações HTTP GET. Se o atributo ValidateAntiForgeryToken for aplicado nos controladores do aplicativo, ele poderá ser substituído pelo atributo IgnoreAntiforgeryToken.
Valide automaticamente tokens antifalsificação apenas para métodos HTTP inseguros
Em vez de aplicar amplamente o atributo ValidateAntiForgeryToken e, em seguida, substituí-lo por atributos IgnoreAntiforgeryToken, o atributo AutoValidateAntiforgeryToken pode ser usado. Esse atributo funciona de forma idêntica ao atributo ValidateAntiForgeryToken, exceto que ele não requer tokens para solicitações feitas usando os seguintes métodos HTTP:
- OBTER
- CABEÇA
- OPÇÕES
- RASTREIO
Recomendamos o uso de AutoValidateAntiforgeryToken de forma ampla para cenários que não sejam de API. Esse atributo garante que as ações POST sejam protegidas por padrão. A alternativa é ignorar tokens de antifalsificação por padrão, a menos que ValidateAntiForgeryToken seja aplicado individualmente aos métodos de ação. É mais provável, neste cenário, que um método de ação POST seja deixado desprotegido por engano, deixando o aplicativo vulnerável a ataques CSRF. Todos os POSTs devem enviar o token antifalsificação.
As APIs não têm um mecanismo automático para enviar a parte nãocookie do token. A implementação provavelmente depende da implementação do código do cliente. Alguns exemplos são mostrados abaixo:
Exemplo de nível de classe:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Exemplo global:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Substituir atributos antifalsificação globais ou de controlador
O filtro IgnoreAntiforgeryToken é usado para eliminar a necessidade de um token antifalsificação para uma determinada ação (ou controlador). Quando aplicado, este filtro substitui os filtros ValidateAntiForgeryToken e AutoValidateAntiforgeryToken especificados a um nível superior (globalmente ou num controlador).
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Atualizar os tokens após a autenticação
Os tokens devem ser atualizados depois de o utilizador ser autenticado, redirecionando-o para uma vista ou página Razor Páginas.
JavaScript, AJAX e SPAs
Em aplicativos tradicionais baseados em HTML, os tokens antifalsificação são passados para o servidor usando campos de formulário ocultos. Em aplicativos e SPAs modernos baseados em JavaScript, muitas solicitações são feitas programaticamente. Essas solicitações AJAX podem usar outras técnicas (como cabeçalhos de solicitação ou cookies) para enviar o token.
Se os cookies forem usados para armazenar tokens de autenticação e autenticar solicitações de API no servidor, o CSRF é um problema potencial. Se o armazenamento local for usado para armazenar o token, a vulnerabilidade CSRF poderá ser atenuada porque os valores do armazenamento local não são enviados automaticamente para o servidor a cada solicitação. Usar o armazenamento local para armazenar o token antifalsificação no cliente e enviar o token como um cabeçalho de solicitação é uma abordagem recomendada.
JavaScript
Usando JavaScript com visualizações, o token pode ser criado usando um serviço de dentro da visualização. Injete o serviço de IAntiforgery na visualização e ligue para GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
O exemplo anterior usa JavaScript para ler o valor de campo oculto para o cabeçalho AJAX POST.
Esta abordagem elimina a necessidade de lidar diretamente com a configuração de cookies do servidor ou lê-los a partir do cliente. No entanto, quando não é possível injetar o serviço IAntiforgery, o JavaScript também pode acessar o token em cookies, obtido a partir de uma solicitação adicional ao servidor (geralmente same-origin), e usar o conteúdo do cookiepara criar um cabeçalho com o valor do token.
Supondo que o script envie o token em um cabeçalho de solicitação chamado X-XSRF-TOKEN, configure o serviço antifalsificação para procurar o cabeçalho X-XSRF-TOKEN:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
O exemplo a seguir adiciona um ponto de extremidade protegido que gravará o token de solicitação em um cookielegível por JavaScript:
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
O exemplo a seguir usa JavaScript para fazer uma solicitação AJAX para obter o token e fazer outra solicitação com o cabeçalho apropriado:
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Cookies de autenticação e antifalsificação do Windows
Ao usar a Autenticação do Windows, os pontos de extremidade da aplicação devem ser protegidos contra ataques CSRF da mesma maneira que são protegidos os cookies. O navegador envia implicitamente o contexto de autenticação para o servidor, assim, os pontos de extremidade precisam ser protegidos contra ataques CSRF.
Estender a antifalsificação
O tipo IAntiforgeryAdditionalDataProvider permite que os desenvolvedores estendam o comportamento do sistema anti-CSRF ao incluir dados adicionais em cada token. O método GetAdditionalData é chamado cada vez que um token de campo é gerado, e o valor de retorno é incorporado no token gerado. Um implementador pode retornar um carimbo de data/hora, um nonce ou qualquer outro valor e, em seguida, chamar ValidateAdditionalData para validar esses dados quando o token for validado. O nome de usuário do cliente já está incorporado nos tokens gerados, portanto, não há necessidade de incluir essas informações. Se um token incluir dados suplementares, mas nenhum IAntiForgeryAdditionalDataProvider estiver configurado, os dados suplementares não serão validados.
Recursos adicionais
A falsificação de solicitação entre sites (também conhecida como XSRF ou CSRF) é um ataque contra aplicativos hospedados na Web pelo qual um aplicativo Web mal-intencionado pode influenciar a interação entre um navegador cliente e um aplicativo Web que confia nesse navegador. Esses ataques são possíveis porque os navegadores da Web enviam alguns tipos de tokens de autenticação automaticamente a cada solicitação para um site. Essa forma de exploração também é conhecida como ataque de um clique ou sequestro de sessão porque o ataque aproveita a sessão previamente autenticada do utilizador.
Um exemplo de um ataque CSRF:
Um utilizador entra em
www.good-banking-site.example.comusando a autenticação por formulários. O servidor autentica o usuário e emite uma resposta que inclui uma autenticação cookie. O site é vulnerável a ataques porque confia em qualquer solicitação recebida com uma autenticação válida cookie.O utilizador visita um site malicioso,
www.bad-crook-site.example.com.O site mal-intencionado,
www.bad-crook-site.example.com, contém um formulário HTML semelhante ao exemplo a seguir:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>Observe que o
actiondo formulário envia informações para o site vulnerável, não para o site malicioso. Esta é a parte "cross-site" da CSRF.O usuário seleciona o botão enviar. O navegador faz a solicitação e inclui automaticamente a autenticação cookie para o domínio solicitado,
www.good-banking-site.example.com.A solicitação é executada no servidor
www.good-banking-site.example.comcom o contexto de autenticação do usuário e pode executar qualquer ação que um usuário autenticado tenha permissão para executar.
Além do cenário em que o usuário seleciona o botão para enviar o formulário, o site mal-intencionado pode:
- Execute um script que envia automaticamente o formulário.
- Envie o envio do formulário como uma solicitação AJAX.
- Oculte o formulário usando CSS.
Esses cenários alternativos não exigem nenhuma ação ou entrada do usuário além de visitar inicialmente o site mal-intencionado.
O uso de HTTPS não impede um ataque CSRF. O site mal-intencionado pode enviar uma solicitação https://www.good-banking-site.example.com/ tão facilmente quanto pode enviar uma solicitação insegura.
Alguns ataques têm como alvo endpoints que respondem a solicitações GET, caso em que uma etiqueta de imagem pode ser usada para executar a ação. Esta forma de ataque é comum em sites de fóruns que permitem imagens, mas bloqueiam JavaScript. Os aplicativos que mudam de estado em solicitações GET, onde variáveis ou recursos são alterados, são vulneráveis a ataques mal-intencionados. As solicitações GET que mudam de estado são inseguras. Uma prática recomendada é nunca alterar o estado em uma solicitação GET.
Os ataques CSRF são possíveis contra aplicativos da Web que usam cookies para autenticação porque:
- Os navegadores armazenam cookies emitidos por um aplicativo da Web.
- Os cookies armazenados incluem cookies de sessão para utilizadores autenticados.
- Os navegadores enviam todos os cookies associados a um domínio para o aplicativo Web a cada solicitação, independentemente de como a solicitação para o aplicativo foi gerada dentro do navegador.
No entanto, os ataques CSRF não se limitam a explorar cookies. Por exemplo, as autenticações Basic e Digest também são vulneráveis. Depois que um usuário entra com autenticação Básica ou Digest, o navegador envia automaticamente as credenciais até que a sessão termine.
Neste contexto, sessão refere-se à sessão do lado do cliente durante a qual o usuário é autenticado. Não está relacionado com sessões do lado do servidor nem com middleware de sessões ASP.NET Core.
Os usuários podem se proteger contra vulnerabilidades CSRF tomando precauções:
- Saia dos aplicativos Web quando terminar de usá-los.
- Limpe os cookies do navegador periodicamente.
No entanto, as vulnerabilidades CSRF são fundamentalmente um problema com o aplicativo Web, não com o usuário final.
Fundamentos de autenticação
A autenticação baseada em Cookieé uma forma popular de autenticação. Os sistemas de autenticação baseados em tokens estão crescendo em popularidade, especialmente para aplicativos de página única (SPAs).
Autenticação baseada em Cookie
Quando um usuário se autentica usando seu nome de usuário e senha, ele recebe um token, contendo um tíquete de autenticação que pode ser usado para autenticação e autorização. O token é armazenado como um cookie que é enviado a cada solicitação feita pelo cliente. A geração e a validação deste cookie são realizadas pelo cookie middleware de autenticação. O middleware serializa uma entidade de usuário em um cookiecriptografado. Em solicitações subsequentes, o middleware valida o cookie, recria o principal e atribui o principal à propriedade HttpContext.User.
Autenticação baseada em tokens
Quando um usuário é autenticado, ele recebe um token (não um token antifalsificação). O token contém informações do usuário na forma de declarações ou um token de referência que aponta o aplicativo para o estado do usuário mantido no aplicativo. Quando um usuário tenta acessar um recurso que requer autenticação, o token é enviado para o aplicativo com um cabeçalho de autorização extra na forma de um token de portador. Essa abordagem torna a aplicação sem estado. Em cada solicitação subsequente, o token é passado na solicitação de validação do lado do servidor. Este token não é criptografado; é codificado. No servidor, o token é decodificado para acessar suas informações. Para enviar o token em solicitações subsequentes, armazene-o no armazenamento local do navegador. Não se preocupe com a vulnerabilidade CSRF se o token estiver armazenado no armazenamento local do navegador. CSRF é uma preocupação quando o token é armazenado num cookie. Para obter mais informações, consulte o problema da GitHub , onde o exemplo de código SPA adiciona dois cookies.
Vários aplicativos hospedados em um domínio
Os ambientes de hospedagem compartilhada são vulneráveis a sequestro de sessão, CSRF de login e outros ataques.
Embora example1.contoso.net e example2.contoso.net sejam hosts diferentes, há uma relação de confiança implícita entre hosts sob o domínio *.contoso.net. Essa relação de confiança implícita permite que hosts potencialmente não confiáveis afetem os cookies uns dos outros (as políticas de mesma origem que regem as solicitações AJAX não se aplicam necessariamente aos cookies HTTP).
Os ataques que exploram cookies confiáveis entre aplicativos hospedados no mesmo domínio podem ser evitados não compartilhando domínios. Quando cada aplicativo é hospedado em seu próprio domínio, não há nenhuma relação de confiança implícita cookie para explorar.
Configuração antifraude do ASP.NET Core
Advertência
ASP.NET Core implementa antifalsificação usando ASP.NET Core Data Protection. A pilha de proteção de dados deve ser configurada para funcionar numa server farm. Para obter mais informações, consulte Configurando a proteção de dados.
O middleware antifalsificação é adicionado ao contêiner de injeção de dependência
No ASP.NET Core 2.0 ou posterior, o FormTagHelper injeta tokens antifalsificação em elementos de formulário HTML. A marcação a seguir em um arquivo Razor gera automaticamente tokens antifalsificação:
<form method="post">
...
</form>
Da mesma forma, IHtmlHelper.BeginForm gera tokens antifalsificação por padrão se o método do formulário não for GET.
A geração automática de tokens antifalsificação para elementos de formulário HTML acontece quando a tag <form> contém o atributo method="post" e uma das seguintes opções é verdadeira:
- O atributo action está vazio (
action=""). - O atributo action não é fornecido (
<form method="post">).
A geração automática de tokens antifalsificação para elementos de formulário HTML pode ser desativada:
Desative explicitamente os tokens antifalsificação com o atributo
asp-antiforgery:<form method="post" asp-antiforgery="false"> ... </form>O elemento de formulário é excluído dos Auxiliares de Tag usando o símbolo de exclusão do Auxiliar de Tag !:
<!form method="post"> ... </!form>Remova o
FormTagHelperda visualização. OFormTagHelperpode ser removido de um modo de exibição adicionando a seguinte diretiva ao modo de exibição Razor:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Observação
Razor Páginas são automaticamente protegidas contra XSRF/CSRF. Para obter mais informações, consulte XSRF/CSRF e Razor Pages.
A abordagem mais comum para se defender contra ataques CSRF é usar o Synchronizer Token Pattern (STP). O STP é usado quando o usuário solicita uma página com dados de formulário:
- O servidor envia um token associado à identidade do usuário atual para o cliente.
- O cliente envia de volta o token para o servidor para verificação.
- Se o servidor receber um token que não corresponda à identidade do usuário autenticado, a solicitação será rejeitada.
O token é único e imprevisível. O token também pode ser usado para garantir o sequenciamento adequado de uma série de solicitações (por exemplo, garantindo a sequência de solicitação de: página 1 > página 2 > página 3). Todos os formulários nos modelos ASP.NET Core MVC e Razor Pages geram tokens antifalsificação. O seguinte par de exemplos de visualização gera tokens antifalsificação:
<form asp-controller="Todo" asp-action="Create" method="post">
...
</form>
@using (Html.BeginForm("Create", "Todo"))
{
...
}
Adicione explicitamente um token antifalsificação a um elemento <form> sem usar Tag Helpers com o HTML helper @Html.AntiForgeryToken:
<form action="/" method="post">
@Html.AntiForgeryToken()
</form>
Em cada um dos casos anteriores, o ASP.NET Core adiciona um campo de formulário oculto semelhante ao exemplo a seguir:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core inclui três filtros para trabalhar com tokens antifalsificação:
Opções antifalsificação
Personalize AntiforgeryOptions em Startup.ConfigureServices:
services.AddAntiforgery(options =>
{
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Defina as propriedades antifalsificação cookie usando as propriedades da classe CookieBuilder, conforme mostrado na tabela a seguir.
| Opção | Descrição |
|---|---|
| Cookie | Determina as configurações usadas para criar os cookies antifalsificação. |
| FormFieldName | O nome do campo de formulário oculto utilizado pelo sistema de proteção contra falsificação para renderizar tokens antifalsificação nas visualizações. |
| HeaderName | O nome do cabeçalho usado pelo sistema antifalsificação. Se null, o sistema considera apenas os dados do formulário. |
| SuppressXFrameOptionsHeader | Especifica se a geração do cabeçalho X-Frame-Options deve ser suprimida. Por padrão, o cabeçalho é gerado com um valor de "SAMEORIGIN". O padrão é false. |
Alguns navegadores não permitem que endpoints inseguros definam cookies com um sinalizador "seguro" ou substituam cookies cujo sinalizador "seguro" esteja definido (para obter mais informações, consulte Depreciar a modificação de cookies "seguros" de origens não seguras). Como misturar pontos de extremidade seguros e inseguros é um cenário comum em aplicações, o ASP.NET Core relaxa a restrição da política segura em alguns cookies, como o antiforjação cookie, ao definir o cookie de SecurePolicy como CookieSecurePolicy.None. Mesmo que um utilizador mal-intencionado roube um antifalsificação cookie, ele também deve roubar o token antifalsificação que normalmente é enviado por meio de um campo de formulário (mais comum) ou através de um cabeçalho de solicitação separado (menos comum), além de roubar a autenticação cookie. Os cookies relacionados com autenticação ou autorização utilizam uma política mais forte do que CookieSecurePolicy.Nonea .
Opcionalmente, pode proteger a antifalsificação cookie em ambientes não-Development usando Secure Sockets Layer (SSL), apenas em HTTPS, com a seguinte AntiforgeryOptions.Cookie configuração de propriedade na classe de Startup da aplicação.
public class Startup
{
public Startup(IConfiguration configuration, IHostEnvironment environment)
{
Configuration = configuration;
Environment = environment;
}
public IConfiguration Configuration { get; }
public IHostEnvironment Environment { get; }
public void ConfigureServices(IServiceCollection services)
{
// Other services are registered here
if (!Environment.IsDevelopment())
{
services.AddAntiforgery(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
}
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Request processing pipeline
}
}
Para obter mais informações, consulte CookieAuthenticationOptions.
Configurar recursos antifalsificação com IAntiforgery
IAntiforgery fornece a API para configurar recursos antifalsificação.
IAntiforgery pode ser solicitado no método Configure da classe Startup.
No exemplo a seguir:
- O middleware da página inicial da aplicação é utilizado para gerar um token antifalsificação e enviá-lo na resposta como cookie.
- O token de solicitação é enviado como um cookie legível por JavaScript com a convenção de nomenclatura padrão do Angular descrita na seção AngularJS .
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
Exigir validação antifalsificação
ValidateAntiForgeryToken é um filtro de ação que pode ser aplicado a uma ação individual, a um controlador ou globalmente. As solicitações feitas para ações que têm esse filtro aplicado são bloqueadas, a menos que a solicitação inclua um token antifalsificação válido.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
{
ManageMessageId? message = ManageMessageId.Error;
var user = await GetCurrentUserAsync();
if (user != null)
{
var result =
await _userManager.RemoveLoginAsync(
user, account.LoginProvider, account.ProviderKey);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
}
}
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
O atributo ValidateAntiForgeryToken requer um token para solicitações para os métodos de ação que ele marca, incluindo solicitações HTTP GET. Se o atributo ValidateAntiForgeryToken for aplicado nos controladores do aplicativo, ele poderá ser substituído pelo atributo IgnoreAntiforgeryToken.
Observação
ASP.NET Core não suporta a adição automática de tokens antifalsificação às solicitações GET.
Valide automaticamente tokens antifalsificação apenas para métodos HTTP inseguros
ASP.NET aplicativos principais não geram tokens antifalsificação para métodos HTTP seguros (GET, HEAD, OPTIONS e TRACE). Em vez de aplicar amplamente o atributo ValidateAntiForgeryToken e, em seguida, substituí-lo por atributos IgnoreAntiforgeryToken, o atributo AutoValidateAntiforgeryToken pode ser usado. Esse atributo funciona de forma idêntica ao atributo ValidateAntiForgeryToken, exceto que ele não requer tokens para solicitações feitas usando os seguintes métodos HTTP:
- OBTER
- CABEÇA
- OPÇÕES
- RASTREIO
Recomendamos o uso de AutoValidateAntiforgeryToken de forma ampla para cenários que não sejam de API. Esse atributo garante que as ações POST sejam protegidas por padrão. A alternativa é ignorar tokens de antifalsificação por padrão, a menos que ValidateAntiForgeryToken seja aplicado individualmente aos métodos de ação. É mais provável, neste cenário, que um método de ação POST seja deixado desprotegido por engano, deixando o aplicativo vulnerável a ataques CSRF. Todos os POSTs devem enviar o token antifalsificação.
As APIs não têm um mecanismo automático para enviar a parte nãocookie do token. A implementação provavelmente depende da implementação do código do cliente. Alguns exemplos são mostrados abaixo:
Exemplo de nível de classe:
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
Exemplo global:
services.AddControllersWithViews(options =>
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
Substituir atributos antifalsificação globais ou de controlador
O filtro IgnoreAntiforgeryToken é usado para eliminar a necessidade de um token antifalsificação para uma determinada ação (ou controlador). Quando aplicado, este filtro substitui os filtros ValidateAntiForgeryToken e AutoValidateAntiforgeryToken especificados a um nível superior (globalmente ou num controlador).
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
{
// no antiforgery token required
}
}
Atualizar os tokens após a autenticação
Os tokens devem ser atualizados depois de o utilizador ser autenticado, redirecionando-o para uma vista ou página Razor Páginas.
JavaScript, AJAX e SPAs
Em aplicativos tradicionais baseados em HTML, os tokens antifalsificação são passados para o servidor usando campos de formulário ocultos. Em aplicativos e SPAs modernos baseados em JavaScript, muitas solicitações são feitas programaticamente. Essas solicitações AJAX podem usar outras técnicas (como cabeçalhos de solicitação ou cookies) para enviar o token.
Se os cookies forem usados para armazenar tokens de autenticação e autenticar solicitações de API no servidor, o CSRF é um problema potencial. Se o armazenamento local for usado para armazenar o token, a vulnerabilidade CSRF poderá ser atenuada porque os valores do armazenamento local não são enviados automaticamente para o servidor a cada solicitação. Usar o armazenamento local para armazenar o token antifalsificação no cliente e enviar o token como um cabeçalho de solicitação é uma abordagem recomendada.
JavaScript
Usando JavaScript com visualizações, o token pode ser criado usando um serviço de dentro da visualização. Injete o serviço de IAntiforgery na visualização e ligue para GetAndStoreTokens:
@{
ViewData["Title"] = "AJAX Demo";
}
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
<input type="hidden" id="RequestVerificationToken"
name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<div class="row">
<p><input type="button" id="antiforgery" value="Antiforgery"></p>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == XMLHttpRequest.DONE) {
if (xhttp.status == 200) {
alert(xhttp.responseText);
} else {
alert('There was an error processing the AJAX request.');
}
}
};
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("antiforgery").onclick = function () {
xhttp.open('POST', '@Url.Action("Antiforgery", "Home")', true);
xhttp.setRequestHeader("RequestVerificationToken",
document.getElementById('RequestVerificationToken').value);
xhttp.send();
}
});
</script>
</div>
Esta abordagem elimina a necessidade de lidar diretamente com a configuração de cookies do servidor ou lê-los a partir do cliente.
O exemplo anterior usa JavaScript para ler o valor de campo oculto para o cabeçalho AJAX POST.
JavaScript também pode acessar tokens em cookies e usar o conteúdo do cookiepara criar um cabeçalho com o valor do token.
context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken,
new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });
Supondo que o script solicite o envio do token em um cabeçalho chamado X-CSRF-TOKEN, configure o serviço antifalsificação para procurar o cabeçalho X-CSRF-TOKEN:
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
O exemplo a seguir usa JavaScript para fazer uma solicitação AJAX com o cabeçalho apropriado:
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
var csrfToken = getCookie("CSRF-TOKEN");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 204) {
alert('Todo item is created successfully.');
} else {
alert('There was an error processing the AJAX request.');
}
}
};
xhttp.open('POST', '/api/items', true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.setRequestHeader("X-CSRF-TOKEN", csrfToken);
xhttp.send(JSON.stringify({ "name": "Learn C#" }));
AngularJS
AngularJS usa uma convenção para abordar CSRF. Se o servidor envia um cookie com o nome XSRF-TOKEN, o serviço $http AngularJS adiciona o valor cookie a um cabeçalho quando envia uma solicitação ao servidor. Este processo é automático. O cliente não precisa definir o cabeçalho explicitamente. O nome do cabeçalho é X-XSRF-TOKEN. O servidor deve detetar esse cabeçalho e validar seu conteúdo.
Para a API do ASP.NET Core funcionar com esta convenção ao iniciar a aplicação:
- Configure a sua aplicação para fornecer um token em um cookie definido como
XSRF-TOKEN. - Configure o serviço antifalsificação para procurar um cabeçalho chamado
X-XSRF-TOKEN, que é o nome de cabeçalho padrão da Angular para enviar o token XSRF.
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
}
Observação
Quando o token antifalsificação é fornecido no cabeçalho da solicitação e na carga útil do formulário, somente o token no cabeçalho é validado.
Cookies de autenticação e antifalsificação do Windows
Ao usar a Autenticação do Windows, os pontos de extremidade da aplicação devem ser protegidos contra ataques CSRF da mesma maneira que são protegidos os cookies. O navegador envia implicitamente o contexto de autenticação para o servidor, assim, os pontos de extremidade precisam ser protegidos contra ataques CSRF.
Estender a antifalsificação
O tipo IAntiforgeryAdditionalDataProvider permite que os desenvolvedores estendam o comportamento do sistema anti-CSRF ao incluir dados adicionais em cada token. O método GetAdditionalData é chamado cada vez que um token de campo é gerado, e o valor de retorno é incorporado no token gerado. Um implementador pode retornar um carimbo de data/hora, um nonce ou qualquer outro valor e, em seguida, chamar ValidateAdditionalData para validar esses dados quando o token for validado. O nome de usuário do cliente já está incorporado nos tokens gerados, portanto, não há necessidade de incluir essas informações. Se um token incluir dados suplementares, mas nenhum IAntiForgeryAdditionalDataProvider estiver configurado, os dados suplementares não serão validados.