É necessário usar a proteção CSRF quando o aplicativo depende da autenticação sem estado (usando algo como HMAC)?
Exemplo:
Temos um único aplicativo página (caso contrário, temos de acrescentar o token em cada link:
<a href="...?token=xyz">...</a>
.O usuário se autentica usando
POST /auth
. Na autenticação bem-sucedida, o servidor retornará algum token.O token será armazenado via JavaScript em alguma variável dentro do aplicativo de página única.
Este token será usado para acessar URLs restritos como
/admin
.O token sempre será transmitido dentro de cabeçalhos HTTP.
Não há sessão Http e cookies.
Pelo que entendi, não deveria (?!) haver possibilidade de usar ataques entre sites, porque o navegador não armazena o token e, portanto, não pode enviá-lo automaticamente ao servidor (é o que aconteceria ao usar Cookies / Sessão).
Estou esquecendo de algo?
Respostas:
Encontrei algumas informações sobre o CSRF + sem usar cookies para autenticação:
https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
"como você não depende de cookies, não precisa se proteger contra solicitações entre sites"
http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/
"Se seguirmos o caminho dos cookies, você realmente precisará executar o CSRF para evitar solicitações entre sites. Isso é algo que podemos esqueça ao usar o JWT como você verá. "
(JWT = Json Web Token, uma autenticação baseada em token para aplicativos sem estado)
http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
"A maneira mais fácil de fazer autenticação sem arriscar vulnerabilidades do CSRF é simplesmente evitar o uso de cookies para identificar o usuário "
http://sitr.us/2011/08/26/cookies-are-bad-for-you.html
"O maior problema com o CSRF é que os cookies não oferecem absolutamente nenhuma defesa contra esse tipo de ataque. Se você estiver usando autenticação de cookies você também deve empregar medidas adicionais para se proteger contra o CSRF. A precaução mais básica que você pode tomar é garantir que seu aplicativo nunca realize efeitos colaterais em resposta a solicitações GET ".
Existem muitas outras páginas, que afirmam que você não precisa de nenhuma proteção CSRF, se você não usa cookies para autenticação. É claro que você ainda pode usar cookies para todo o resto, mas evite armazenar qualquer coisa
session_id
dentro dele.Se você precisar se lembrar do usuário, existem 2 opções:
localStorage
: Um armazenamento de valores-chave no navegador. Os dados armazenados estarão disponíveis mesmo após o usuário fechar a janela do navegador. Os dados não são acessíveis por outros sites, porque cada site recebe seu próprio armazenamento.sessionStorage
: Também um repositório de dados do navegador. A diferença é: Os dados são excluídos quando o usuário fecha a janela do navegador. Mas ainda é útil se o seu aplicativo da web consistir em várias páginas. Então você pode fazer o seguinte:sessionStorage
sessionStorage
sessionStorage
ou aguardar que o usuário feche a janela do navegador, o que limpará todos os dados armazenados.(para ambos, dê uma olhada aqui: http://www.w3schools.com/html/html5_webstorage.asp )
Existem padrões oficiais para autenticação de token?
JWT (Json Web Token): Acho que ainda é um rascunho, mas já é usado por muitas pessoas e o conceito parece simples e seguro. (IETF: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25 )
Também existem bibliotecas para muitos frameworks disponíveis. Basta pesquisar no google!
fonte
http://.../someRestResource?method=POST
. Portanto, é basicamente umaGET
solicitação, mas o Aplicativo de Servidor a interpreta como umaPOST
solicitação, porque foi configurado para usar omethod
parâmetro em vez do cabeçalho HTTP....
Em relação aos navegadores da Web comuns, eles aplicam a mesma política de origem e só executamGET
solicitações para servidores estrangeiros. Embora possa ser possível executarPOST
solicitações se o navegador da web não aplicar esses padrões da web (bug, malware).Server Side App
: ainda não é possível enviar um corpo de solicitação, porque os navegadores comuns não permitem isso. No entanto, se o Aplicativo do servidor permitirmethod=POST
, ele também poderábody={someJson}
substituir o corpo da solicitação padrão. É um projeto de API muito ruim e extremamente arriscado. No entanto, se o aplicativo do servidor permitir,http://...?method=POST&body={someJson}
você deve realmente pensar demais no que fez lá e por que e se for necessário. (Eu diria que em 99,9999% dos casos é não necessário). Além disso, os navegadores podem enviar apenas alguns kilobytes dessa maneira.TL; DR
Um JWT, se usado sem cookies, nega a necessidade de um token CSRF - MAS! armazenando o JWT em session / localStorage, você expõe o JWT e a identidade do usuário se o site tiver uma vulnerabilidade XSS (bastante comum). É melhor adicionar uma
csrfToken
chave para a JWT e armazenar a JWT em um cookie comsecure
ehttp-only
conjunto de atributos.Leia este artigo com uma boa descrição para obter mais informações https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
Portanto, você precisará armazenar o csrfToken em localStorage / sessionStorage, bem como no próprio JWT (que é armazenado em um cookie seguro apenas para http). Em seguida, para proteção csrf, verifique se o token csrf no JWT corresponde ao cabeçalho csrf-token enviado.
fonte