<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lucas Fernandes</title>
    <description>The latest articles on DEV Community by Lucas Fernandes (@lucasfpds).</description>
    <link>https://dev.to/lucasfpds</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1229249%2F0905d21b-22b0-4053-87a7-2195c06eab8a.png</url>
      <title>DEV Community: Lucas Fernandes</title>
      <link>https://dev.to/lucasfpds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lucasfpds"/>
    <language>en</language>
    <item>
      <title>Como proteger sua aplicação frontend contra ataques CSRF</title>
      <dc:creator>Lucas Fernandes</dc:creator>
      <pubDate>Sat, 26 Sep 2026 19:22:15 +0000</pubDate>
      <link>https://dev.to/lucasfpds/como-proteger-sua-aplicacao-frontend-contra-ataques-csrf-1iip</link>
      <guid>https://dev.to/lucasfpds/como-proteger-sua-aplicacao-frontend-contra-ataques-csrf-1iip</guid>
      <description>&lt;p&gt;Sabe o que é e como se proteger de ataques &lt;strong&gt;CSRF (Cross-Site Request Forgery)&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;CSRF é um tipo de ataque no qual um usuário autenticado é induzido a executar uma ação que não pretendia realizar em uma aplicação.&lt;/p&gt;

&lt;p&gt;Imagine, por exemplo, que você está logado em um site de compras e recebe um e-mail contendo um link aparentemente inofensivo. Ao acessar esse link, uma página maliciosa tenta realizar uma ação no site em que você já está autenticado.&lt;/p&gt;

&lt;p&gt;Se a aplicação não possuir mecanismos adequados de proteção, o navegador pode enviar automaticamente seus cookies de autenticação e a operação pode ser executada como se tivesse sido solicitada por você.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx9b62ai6na0pce41cx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx9b62ai6na0pce41cx9.png" alt="Person scared by something they saw on the computer" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Existem diferentes formas de reduzir o risco desse tipo de ataque. Neste artigo, vamos abordar principalmente o uso de &lt;strong&gt;tokens CSRF&lt;/strong&gt;, com foco na comunicação entre frontend e backend.&lt;/p&gt;

&lt;p&gt;É importante destacar que o &lt;strong&gt;token CSRF não é o mesmo token normalmente utilizado para autenticar ou manter a sessão de um usuário&lt;/strong&gt;. Enquanto tokens de autenticação, cookies de sessão ou access tokens identificam o usuário e controlam seu acesso à aplicação, o token CSRF tem outra função: ajudar o servidor a verificar se uma requisição que altera dados foi realmente iniciada pela aplicação legítima.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usando tokens CSRF
&lt;/h2&gt;

&lt;p&gt;Uma das abordagens mais conhecidas para prevenir ataques CSRF é o uso de tokens.&lt;/p&gt;

&lt;p&gt;O servidor gera um valor aleatório e imprevisível, associa esse valor à sessão do usuário e o disponibiliza para a aplicação.&lt;/p&gt;

&lt;p&gt;Quando o frontend realiza uma operação que altera o estado da aplicação, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;POST&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PUT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PATCH&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ele envia também o token CSRF.&lt;/p&gt;

&lt;p&gt;O backend verifica esse token antes de permitir que a operação seja executada.&lt;/p&gt;

&lt;p&gt;O fluxo pode ser representado da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Servidor gera o token
        ↓
Frontend recebe o token
        ↓
Frontend envia o token na requisição
        ↓
Backend valida o token
        ↓
Requisição é aceita ou rejeitada
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É importante lembrar que requisições como &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt; e &lt;code&gt;OPTIONS&lt;/code&gt; normalmente não precisam utilizar token CSRF, pois não deveriam realizar operações que alteram dados da aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como usar tokens CSRF em JavaScript?
&lt;/h2&gt;

&lt;p&gt;Uma possível implementação pode seguir os passos abaixo.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Gerar o token CSRF no servidor
&lt;/h3&gt;

&lt;p&gt;O token deve ser gerado utilizando uma fonte de aleatoriedade criptograficamente segura.&lt;/p&gt;

&lt;p&gt;Por isso, não é recomendado utilizar &lt;code&gt;Math.random()&lt;/code&gt; para gerar tokens relacionados à segurança.&lt;/p&gt;

&lt;p&gt;Em uma aplicação Node.js, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateCSRFToken&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse código gera um token aleatório de 256 bits.&lt;/p&gt;

&lt;p&gt;O servidor também deve manter alguma forma de validar posteriormente esse token, geralmente associando-o à sessão do usuário.&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ Disponibilizar o token para o frontend
&lt;/h3&gt;

&lt;p&gt;Uma aplicação renderizada pelo servidor pode disponibilizar o token diretamente no HTML.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"csrf-token"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"TOKEN_GERADO_PELO_SERVIDOR"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No frontend, o JavaScript pode recuperá-lo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;csrfToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meta[name="csrf-token"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outra possibilidade, bastante comum em aplicações SPA, é utilizar um cookie específico para o token CSRF.&lt;/p&gt;

&lt;p&gt;A arquitetura adotada depende da estratégia utilizada pela aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  3️⃣ Enviar o token nas requisições
&lt;/h2&gt;

&lt;p&gt;Para aplicações que utilizam AJAX ou APIs, uma prática comum é enviar o token através de um &lt;strong&gt;header HTTP personalizado&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Utilizando Axios:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;csrfToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meta[name="csrf-token"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/cart/add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-CSRF-Token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;csrfToken&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O frontend obtém o token fornecido pelo servidor.&lt;/li&gt;
&lt;li&gt;Uma requisição &lt;code&gt;POST&lt;/code&gt; é enviada para &lt;code&gt;/api/cart/add&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;O token é enviado através do header &lt;code&gt;X-CSRF-Token&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;O backend valida esse valor antes de processar a operação.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Também é possível enviar o token no corpo da requisição:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;csrfToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meta[name="csrf-token"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/cart/add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;csrfToken&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Embora as duas abordagens sejam possíveis, em aplicações AJAX ou SPA o uso de um &lt;strong&gt;header personalizado&lt;/strong&gt; costuma deixar essa responsabilidade mais explícita.&lt;/p&gt;

&lt;p&gt;Também é importante evitar colocar tokens CSRF em URLs ou query strings, como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/cart/add?csrfToken=TOKEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso pode fazer com que o token apareça em locais como logs, históricos do navegador, ferramentas de analytics ou outros sistemas intermediários.&lt;/p&gt;

&lt;h2&gt;
  
  
  O backend precisa validar o token
&lt;/h2&gt;

&lt;p&gt;A existência de um token no frontend, por si só, não oferece proteção.&lt;/p&gt;

&lt;p&gt;O backend deve validar o token recebido antes de executar qualquer operação protegida.&lt;/p&gt;

&lt;p&gt;Um exemplo simplificado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/cart/add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;csrfToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-csrf-token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;validateCSRFToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;csrfToken&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid CSRF token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Continua o processamento da requisição&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou seja, o frontend é responsável por &lt;strong&gt;obter e enviar o token&lt;/strong&gt;, enquanto o backend é responsável por &lt;strong&gt;validá-lo&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  E os cookies HttpOnly?
&lt;/h2&gt;

&lt;p&gt;Aqui existe uma diferença importante.&lt;/p&gt;

&lt;p&gt;Cookies utilizados para armazenar informações de &lt;strong&gt;sessão ou autenticação&lt;/strong&gt; normalmente devem utilizar configurações como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HttpOnly
Secure
SameSite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A flag &lt;code&gt;HttpOnly&lt;/code&gt; impede que JavaScript executado no navegador leia diretamente aquele cookie através de &lt;code&gt;document.cookie&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Isso é especialmente útil para cookies de autenticação.&lt;/p&gt;

&lt;p&gt;Porém, se o frontend precisar ler um token CSRF para colocá-lo em um header HTTP, esse token não poderá estar exclusivamente em um cookie &lt;code&gt;HttpOnly&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Caso contrário, o JavaScript não conseguiria acessá-lo.&lt;/p&gt;

&lt;p&gt;Por isso, é importante diferenciar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cookie de sessão
→ normalmente HttpOnly

Token CSRF utilizado pelo JavaScript
→ precisa estar disponível para o frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dependendo da arquitetura utilizada, o token pode estar presente no HTML, em uma meta tag ou em um cookie específico acessível pelo frontend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Synchronizer Token Pattern
&lt;/h2&gt;

&lt;p&gt;Uma das estratégias mais conhecidas é o &lt;strong&gt;Synchronizer Token Pattern&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nesse modelo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sessão do usuário
       ↓
Servidor gera um token CSRF
       ↓
Token é enviado para o frontend
       ↓
Frontend envia o token novamente
       ↓
Servidor compara com o token esperado
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O token deve ser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;imprevisível;&lt;/li&gt;
&lt;li&gt;suficientemente longo;&lt;/li&gt;
&lt;li&gt;gerado de maneira criptograficamente segura;&lt;/li&gt;
&lt;li&gt;associado à sessão do usuário.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se o token recebido não corresponder ao valor esperado, o servidor rejeita a operação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Double Submit Cookie
&lt;/h2&gt;

&lt;p&gt;Outra estratégia é conhecida como &lt;strong&gt;Double Submit Cookie&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nesse modelo, o servidor fornece um token em um cookie:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XSRF-TOKEN=abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O frontend lê esse token e envia o mesmo valor também em um header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;X-XSRF-TOKEN: abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A requisição acaba contendo as duas informações:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cookie:
XSRF-TOKEN=abc123

Header:
X-XSRF-TOKEN: abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O servidor verifica se os valores são válidos antes de aceitar a operação.&lt;/p&gt;

&lt;p&gt;Frameworks e bibliotecas podem implementar variações dessa estratégia automaticamente.&lt;/p&gt;

&lt;p&gt;É importante observar que existem versões mais robustas desse padrão, nas quais o token também é associado criptograficamente à sessão do usuário.&lt;/p&gt;

&lt;h2&gt;
  
  
  HttpOnly não protege um token exposto no HTML
&lt;/h2&gt;

&lt;p&gt;É importante também entender uma limitação.&lt;/p&gt;

&lt;p&gt;Imagine que o servidor configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: csrfToken=abc123; HttpOnly
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mas ao mesmo tempo coloque o mesmo token no HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"csrf-token"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"abc123"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um JavaScript malicioso não conseguirá acessar diretamente o cookie &lt;code&gt;HttpOnly&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Porém, poderá acessar a meta tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meta[name="csrf-token"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Portanto, tornar o cookie &lt;code&gt;HttpOnly&lt;/code&gt; não protege o token caso o mesmo valor esteja disponível em algum local acessível ao JavaScript.&lt;/p&gt;

&lt;p&gt;Essa distinção é especialmente importante quando falamos sobre ataques XSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSRF e XSS são problemas diferentes
&lt;/h2&gt;

&lt;p&gt;Tokens CSRF ajudam a impedir que sites externos consigam forjar determinadas operações em nome de um usuário autenticado.&lt;/p&gt;

&lt;p&gt;Eles não devem ser considerados uma proteção contra &lt;strong&gt;Cross-Site Scripting (XSS)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Se um atacante conseguir executar JavaScript dentro da própria origem da aplicação, ele pode, dependendo do cenário:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;acessar informações disponíveis no DOM;&lt;/li&gt;
&lt;li&gt;obter tokens acessíveis ao JavaScript;&lt;/li&gt;
&lt;li&gt;realizar requisições em nome do usuário;&lt;/li&gt;
&lt;li&gt;manipular a aplicação diretamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por isso, CSRF e XSS precisam ser tratados como problemas de segurança distintos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outras medidas importantes contra CSRF
&lt;/h2&gt;

&lt;p&gt;Além dos tokens CSRF, existem outras proteções que podem ser utilizadas em conjunto.&lt;/p&gt;

&lt;h3&gt;
  
  
  SameSite nos cookies
&lt;/h3&gt;

&lt;p&gt;A propriedade &lt;code&gt;SameSite&lt;/code&gt; ajuda a controlar quando cookies podem ser enviados em requisições iniciadas a partir de outros sites.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Existem três valores principais:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SameSite=Strict
SameSite=Lax
SameSite=None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Strict&lt;/code&gt; oferece uma política mais restritiva.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Lax&lt;/code&gt; permite alguns fluxos de navegação entre sites, mas reduz vários cenários tradicionais de CSRF.&lt;/p&gt;

&lt;p&gt;Já &lt;code&gt;SameSite=None&lt;/code&gt; permite o envio do cookie em contexto cross-site e exige também &lt;code&gt;Secure&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A configuração correta depende do funcionamento da aplicação.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SameSite&lt;/code&gt; deve ser entendido como uma camada adicional de proteção e não necessariamente como substituto de todas as demais medidas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validar Origin e Referer
&lt;/h3&gt;

&lt;p&gt;O backend também pode verificar headers como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Origin
Referer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Origin: https://meusite.com
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O servidor pode verificar se a requisição está vindo de uma origem esperada antes de permitir determinadas operações.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fetch Metadata
&lt;/h3&gt;

&lt;p&gt;Navegadores modernos também enviam headers conhecidos como &lt;strong&gt;Fetch Metadata&lt;/strong&gt;, como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Sec-Fetch-Site
Sec-Fetch-Mode
Sec-Fetch-Dest
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Sec-Fetch-Site: same-origin
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esses headers podem ajudar o servidor a identificar requisições iniciadas a partir de outros sites.&lt;/p&gt;

&lt;p&gt;Eles podem ser utilizados como uma camada adicional de proteção.&lt;/p&gt;

&lt;h3&gt;
  
  
  Não alterar estado através de GET
&lt;/h3&gt;

&lt;p&gt;Uma regra importante é evitar operações como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /delete-user?id=123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ou:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /purchase?id=456
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Requisições &lt;code&gt;GET&lt;/code&gt; devem ser utilizadas para leitura de recursos e não para operações que alterem dados.&lt;/p&gt;

&lt;p&gt;Operações de alteração devem utilizar métodos apropriados, como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST
PUT
PATCH
DELETE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;com as respectivas proteções de segurança.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reautenticação para operações críticas
&lt;/h3&gt;

&lt;p&gt;Para operações muito sensíveis, a aplicação também pode exigir uma confirmação adicional.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alterar senha
Alterar e-mail
Cadastrar uma nova conta bancária
Realizar uma transferência financeira
Excluir permanentemente uma conta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesses casos, solicitar novamente a senha, MFA ou outra confirmação pode adicionar uma camada extra de segurança.&lt;/p&gt;

&lt;p&gt;Isso não substitui as proteções contra CSRF, mas pode reduzir o impacto de diferentes tipos de ataques.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same-Origin Policy não elimina CSRF
&lt;/h2&gt;

&lt;p&gt;Outro ponto importante é entender a relação entre CSRF e &lt;strong&gt;Same-Origin Policy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A Same-Origin Policy é uma proteção implementada pelos navegadores que limita como páginas de uma origem conseguem acessar dados de outra origem.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://site-malicioso.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;normalmente não consegue ler livremente informações retornadas por:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://meubanco.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porém, isso não significa necessariamente que o navegador não possa &lt;strong&gt;enviar uma requisição&lt;/strong&gt; para &lt;code&gt;meubanco.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Essa diferença é justamente uma das razões pelas quais ataques CSRF são possíveis.&lt;/p&gt;

&lt;p&gt;De forma simplificada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Same-Origin Policy
↓
limita principalmente a leitura de recursos entre origens

CSRF
↓
explora o envio de requisições usando a sessão já autenticada da vítima
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por isso, a Same-Origin Policy não deve ser considerada uma proteção suficiente contra CSRF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Ataques CSRF exploram principalmente o fato de que navegadores podem enviar automaticamente credenciais, como cookies de sessão, em determinadas requisições.&lt;/p&gt;

&lt;p&gt;Uma estratégia de proteção pode combinar diferentes mecanismos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tokens CSRF
+
SameSite
+
validação de Origin/Referer
+
Fetch Metadata
+
cookies Secure e HttpOnly para autenticação
+
operações que alteram estado usando métodos HTTP adequados
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O ponto principal é lembrar que a proteção contra CSRF não deve depender apenas do frontend.&lt;/p&gt;

&lt;p&gt;O frontend pode obter e enviar o token, mas é o &lt;strong&gt;backend que precisa verificar se a requisição é legítima antes de executar a operação&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Segurança funciona melhor quando diferentes mecanismos são utilizados em conjunto, reduzindo a dependência de uma única camada de proteção.&lt;/p&gt;

&lt;h2&gt;
  
  
  Glossário
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pt.wikipedia.org/wiki/Cross-site_Request_Forgery" rel="noopener noreferrer"&gt;CSRF (Cross-Site Request Forgery)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP — Cross-Site Request Forgery Prevention Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Overview" rel="noopener noreferrer"&gt;Solicitações HTTP — MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Cookies" rel="noopener noreferrer"&gt;Cookies HTTP — MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value" rel="noopener noreferrer"&gt;SameSite — MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Fetch_metadata_request_header" rel="noopener noreferrer"&gt;Fetch Metadata — MDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>security</category>
    </item>
  </channel>
</rss>
