- Ao pensar sobre Cross-Site Request, no início não ficava claro por que proteção contra CSRF e CORS eram ambas necessárias. Mas, para explicar isso, são necessárias muitas palavras
CSRF e CORS
- CSRF (Cross-Site Request Forgery)
- Era comum no passado, mas hoje quase não é um problema, já que a maioria dos frameworks web oferece proteção por padrão
- Forma de ataque: induzir o usuário a clicar em um formulário em um site malicioso para enviar uma requisição cross-site
- Forma de defesa: verificar se a requisição não veio de outro site
- CORS (Cross-Origin Resource Sharing)
- Faz parte da especificação HTTP e define como permitir determinadas requisições cross-site
- Usa preflight request e cabeçalhos de resposta para especificar de quais origens (
origin) as requisições podem ser enviadas
Então, requisições cross-site são permitidas por padrão e por isso a proteção contra CSRF é necessária, ou são bloqueadas por padrão e o CORS é necessário para permiti-las? A resposta é as duas coisas.
Funcionamento básico
- Política de mesma origem (Same-origin policy)
- Política de segurança imposta pelo navegador
- Em geral, escrita (Write) cross-site é permitida, mas leitura (Read) é proibida
- Por exemplo, o navegador permite uma requisição POST via formulário, mas não permite ler a resposta
- Política de cookies SameSite
- Em 2019, o comportamento padrão dos cookies mudou
- Antes, os cookies sempre eram enviados mesmo em requisições cross-site
- O novo atributo
SameSitefoi adicionado, e o valor padrão passou a serLax - Em 2025, 96% dos navegadores suportam o atributo
SameSite, e 75% suportam o novo padrão (Lax) - Porém, o Safari não o aplicou como padrão, e o UCBrowser ainda não oferece suporte
- Diferença entre Site e Origin
- Origin: combinação de
protocolo + hostname + porta - Site: combinação de
protocolo + domínio de topo + 1(subdomínios e portas são ignorados)
- Origin: combinação de
CORS
- CORS é uma forma de permitir exceções à política de mesma origem para determinadas origens (
origin) - Antes de enviar a requisição, o navegador envia uma preflight request do tipo
OPTIONS - O servidor define as regras permitidas por meio dos cabeçalhos de resposta (usando cabeçalhos
Access-Control-*) - Tipos de requisição aos quais o CORS se aplica:
fetcheXMLHttpRequest- fontes web
- texturas WebGL
- imagens/frames de vídeo desenhados com
drawImageemcanvas - imagens usadas na propriedade CSS
shape-outside
- Mas o envio de formulários é uma exceção, e o CORS não se aplica
- A tag
<form>do HTML 4.0 já permitia requisições cross-site há muito tempo - Portanto, servidores antigos já deveriam ter sido projetados para se defender de ataques CSRF
- Para compartilhar a resposta, o servidor precisa definir
Access-Control-Allow-Origin, mas a própria requisição é aceita mesmo sem preflight
- A tag
Pergunta: como a política
SameSitee esse comportamento mantêm consistência entre si?
Métodos de proteção contra CSRF
- Requisições de escrita cross-site são permitidas, mas a resposta não é compartilhada
- A maioria dos sites não quer permitir escrita cross-site
- Método padrão de defesa contra CSRF
- Incluir e validar um token CSRF específico por usuário na requisição
- Formas de uso:
- Envio de formulário: adicionar o token em um campo oculto (
hidden input) - Requisições JS: armazenar em cookie ou tag
meta, depois incluí-lo no cabeçalho ou nos parâmetros da requisição
- Envio de formulário: adicionar o token em um campo oculto (
- Requisições JS originalmente já são bloqueadas por padrão quando são cross-site
- Mas são permitidas em requisições same-site
- Ao incluir o token CSRF, é possível validar todas as requisições da mesma forma
- Benefícios adicionais de segurança
- Funciona com base na premissa de que o navegador deve bloquear por padrão a leitura da resposta
- É mais seguro do que verificar apenas o cabeçalho
Origin
Pergunta: em alguns frameworks, o token CSRF muda periodicamente. Por quê?
O papel do navegador
- O ponto central da segurança web depende de o navegador ser confiável
- O navegador:
- impõe a política de mesma origem
- bloqueia a leitura quando a resposta não é permitida
- decide se aplica o padrão
SameSite=Lax - implementa o CORS e envia preflight requests seguras
Precisamos confiar no navegador que estamos usando.
Conclusão
- Se
SameSite=Laxfosse suportado por 100% dos navegadores, a segurança seria ainda maior, mas
atualmente ainda existe a exceção de permitir requisições POST cross-site - Portanto, desenvolvedores ainda precisam considerar continuamente a proteção contra CSRF
"A internet está ficando cada vez mais segura, mas ao mesmo tempo a compatibilidade com o passado está diminuindo."
1 comentários
Comentário do Hacker News
CORS é um mecanismo pelo qual o servidor informa explicitamente ao navegador quais requisições cross-origin podem ler a resposta
A proteção contra CSRF impede que requisições cross-origin maliciosas executem ações não autorizadas em nome de um usuário autenticado
A proteção contra CSRF trata de proteger escritas, enquanto CORS trata de proteger leituras
Requisições iniciadas por JS, por padrão, não permitem cross-site
fetch()com apenas os cabeçalhos permitidosAcho que existe uma explicação melhor sobre esse tema
Resposta à pergunta do post do blog
<form>do HTML 4.0 pode enviar requisições simples para qualquer origemEm 2022, foi adicionado um parágrafo ao artigo do MDN sobre CORS para esclarecer a origem do termo "requisições simples"
É confuso que SameSite tenha sido adicionado independentemente do preflight do CORS
Pode parecer seguro mesmo sem usar csrf, mas algumas bibliotecas (por exemplo, django rest framework) conseguem processar formulários HTML quando o cabeçalho content-type está definido
Pergunta sobre por que tokens CSRF são rotacionados
Pedido de um fluxograma para esse tema complexo
Essas coisas não ajudam com rastreamentos de diagnóstico fáceis
Não entendo por que, antes do surgimento do CORS, era possível enviar requisições para endpoints arbitrários diferentes da origem da página, mas sem poder ver a resposta
Confusão sobre a proteção contra CSRF