Pular para o conteudo principal

Autenticação em SPAs: por que localStorage quase sempre e ma ideia

Como pensar armazenamento de credencial no browser sem transformar comodidade de implementação em risco silencioso para o produto.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

Trilha

Trilha para entrevistas de senior frontend

Etapa 14 / 15

O problema

Tem implementação de auth em SPA que segue este caminho:

  1. faz login
  2. recebe token
  3. salva token no localStorage
  4. manda token em toda request

Funciona.

E exatamente por funcionar fácil que isso vira default em muito projeto.

O problema e que facilidade de acesso para o seu código também significa facilidade de acesso para qualquer script que consiga rodar naquela pagina.

Modelo mental

Pense assim:

o problema do localStorage não e guardar dado no browser. O problema e guardar credencial sensivel em um lugar acessivel a JavaScript da pagina.

Se houver XSS ou script comprometido, o invasor não precisa adivinhar muito.

Ele pode simplesmente ler a credencial.

Isso aumenta bastante o raio de dano.

Quebrando o problema

localStorage e fácil para você e para o atacante

Seu app pode ler com facilidade.

Um script injetado também.

Esse e o ponto central.

Não e uma discussão sobre gosto.

E sobre superficie de exposição.

Quando a credencial fica em cookie com HttpOnly, o JavaScript da pagina não consegue ler o valor diretamente.

Isso não elimina todos os problemas.

Mas tira uma classe importante de acesso trivial ao token.

Claro, continuam existindo cuidados como:

  • SameSite
  • Secure
  • CSRF quando fizer sentido
  • autorização no backend

Mas o desenho de exposição melhora.

Nem toda SPA consegue o mesmo fluxo do mesmo jeito

Arquitetura importa.

Se existe backend próprio e sessao via cookie, o default costuma ficar melhor com cookie HttpOnly.

Se o contexto e diferente, a conversa também muda.

O erro e transformar conveniencia de implementação no principal critério de segurança.

Quase sempre ma ideia não e o mesmo que “nunca”

Esse ponto importa.

Se o requisito for diferente, o time pode assumir trade-off conscientemente.

Mas, para isso, precisa responder:

  • por que esse risco vale?
  • que mitigacoes existem?
  • que alternativa foi descartada e por que?

Sem essa conversa, localStorage vira só atalho.

Exemplo simples

Imagine uma SPA com token JWT salvo em localStorage.

Agora imagine um XSS em algum ponto da aplicação ou de biblioteca carregada.

O script malicioso pode:

  • ler o token
  • mandar para fora
  • reutilizar enquanto estiver valido

Se o desenho usa cookie HttpOnly, esse acesso direto ao valor já não acontece do mesmo jeito.

Isso não torna a aplicação magica.

Só reduz uma superficie bem relevante.

Erros comuns

  • Defender localStorage só porque e simples de programar.
  • Tratar “stateless” como se resolvesse segurança sozinho.
  • Achar que cookie HttpOnly elimina toda preocupação restante.
  • Discutir armazenamento sem falar de XSS e exposição.
  • Falar “nunca use” sem explicar o mecanismo do risco.

Como um senior pensa

Quem tem mais experiência tenta sair do dogma e voltar para a pergunta certa:

“Quem consegue ler essa credencial neste desenho? Se houver script comprometido, qual o raio de dano?”

Essa pergunta deixa a conversa mais honesta.

Porque o debate deixa de ser framework war e volta a ser modelagem de risco.

O que o entrevistador quer ver

Em entrevista, esse tema mede maturidade de segurança aplicada.

O avaliador quer ver se você:

  • entende o problema de exposição ao JavaScript da pagina
  • compara alternativas com trade-off
  • evita absolutismo vazio
  • sabe defender um default melhor

Uma resposta forte costuma soar assim:

“Eu evitaria localStorage como default para credencial de auth em SPA porque qualquer script que rode na pagina consegue ler esse valor. Quando o desenho permite, prefiro cookie HttpOnly para reduzir essa exposição. Não e que localStorage seja magicamente proibido sempre, mas ele costuma ser um default pior do ponto de vista de risco.”

localStorage não e ruim porque persiste. E ruim porque expoe a credencial ao ambiente JavaScript da pagina.

Conveniencia de implementação raramente deveria decidir sozinha onde sua credencial mora.

Resumo rápido

O que vale manter na cabeça

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Parte da trilha: Trilha para entrevistas de senior frontend (14/15)

Próximo artigo Entradas e APIs Mais Seguras Artigo anterior Auth vs Authz: a diferença que todo mundo confunde

Continue explorando

Artigos relacionados