← Todas as verificações
SegurançaSeveridade típica: Alto

Tokens em armazenamento local

Deteta se o teu JavaScript guarda tokens em localStorage/sessionStorage, vulneráveis a roubo via XSS.

O que verifica

Este scanner deteta se o teu JavaScript guarda tokens de sessão ou de autenticação no localStorage ou sessionStorage do navegador. Identifica quando as credenciais de acesso ficam guardadas num sítio acessível a partir do próprio código da página.

Porque importa

Os dados guardados no localStorage são acessíveis por qualquer JavaScript que corra na página, por isso se houver uma falha de XSS um atacante pode roubar o token e fazer-se passar pelo utilizador. É um sítio muito menos seguro para credenciais do que uma cookie bem protegida.

Como se corrige

Sempre que possível, guarda os tokens de sessão em cookies com os atributos HttpOnly e Secure, que o JavaScript não consegue ler. Se precisas de usar tokens no cliente, reduz a sua duração e combina isto com uma boa proteção contra XSS.

Como funciona esta verificação

O Scanaris lê o JavaScript da tua página principal, incluindo os scripts que carrega a partir do teu domínio, e procura chamadas a localStorage.setItem ou sessionStorage.setItem cuja chave sugira uma credencial: token, jwt, auth, secret, password, api_key, access, refresh ou bearer. Se encontrar uma, abre um achado de severidade baixa. É baixa porque guardar um token no navegador não é uma brecha por si só; torna-se numa quando se combina com qualquer injeção de script, e por isso vale a pena sabê-lo.

Porque importa

Tudo o que está no localStorage pode ser lido por qualquer código que corra na tua página: os teus scripts, os de terceiros que carregas (analítica, chats, widgets) e qualquer script que um atacante consiga injetar. Uma única vulnerabilidade XSS, no teu código ou numa dependência, basta para que localStorage.getItem('token') viaje para um servidor alheio e alguém use a sessão do teu utilizador a partir de outro sítio, sem a palavra-passe dele e sem que ele repare. Um cookie com HttpOnly é invisível para o JavaScript, por isso esse mesmo XSS não o consegue roubar; pode fazer pedidos enquanto a página está aberta, o que é mau, mas não levar a sessão.

De onde vem normalmente

Da configuração por defeito de muitas bibliotecas de autenticação em aplicações de página única. O cliente do Supabase para o navegador guarda a sessão em localStorage se não lhe disseres outra coisa, tal como muitos exemplos de JWT "feito à mão" com Express. O Lovable, o Bolt e o v0 geram esse padrão porque é o que aparece na documentação de início rápido.

Como corrigir

  • Sessão em cookies HttpOnly. Se tens servidor (Next.js, Nuxt, Express, uma Edge Function), que seja ele a receber o token do fornecedor e a guardá-lo num cookie com HttpOnly, Secure e SameSite=Lax. O navegador envia-o sozinho e nunca o vê.
  • Com Supabase: em Next.js ou Nuxt usa @supabase/ssr, que guarda a sessão em cookies; numa SPA pura sem servidor, aceita o risco e compensa-o com uma CSP estrita, porque não há outro sítio onde a guardar.
  • Tokens curtos e renovação segura. Se o token de acesso tem de viver em memória ou no storage, que expire em minutos e que o de renovação vá num cookie HttpOnly.
  • Memória em vez de storage. Guardar o token numa variável de JavaScript (não no storage) protege-o de scripts que leiam o storage, embora não de um XSS ativo na mesma página. Melhor do que localStorage, pior do que um cookie.
  • Reduz a superfície de XSS. Uma CSP sem 'unsafe-inline' em script-src, sanitizar qualquer HTML de utilizador e rever os scripts de terceiros que carregas. É a defesa que faz com que o token no storage não importe.

Confirma que está corrigido

curl -s https://oteudominio.com | grep -oE 'src="[^"]+\.js[^"]*"' | cut -d'"' -f2 | head -3
curl -s https://oteudominio.com/assets/index-XXXX.js | grep -oE "(local|session)Storage\.setItem\([^)]{0,60}" | head

Se o segundo comando devolver linhas com token, auth ou semelhantes na chave, o padrão continua lá. Nas ferramentas do navegador, separador Aplicação, podes ver o que a tua app guarda no storage depois de iniciar sessão.

Perguntas frequentes

O Supabase guarda a sessão em localStorage por defeito. Está mal?

É o compromisso que uma SPA sem servidor assume. Se tens servidor, muda para @supabase/ssr. Se não, cuida da CSP e dos scripts de terceiros: esse token é tão seguro como a página que o rodeia.

O sessionStorage é mais seguro do que o localStorage?

Só na duração: apaga-se ao fechar o separador. Qualquer script da página lê-o na mesma.

Porque é severidade baixa se pode roubar a sessão?

Porque precisa de outra vulnerabilidade (um XSS) para ser explorado. O check avisa-te para decidires com informação; se o teu site já tem uma CSP estrita e não mostra conteúdo de utilizador sem sanitizar, o risco real é pequeno.

Verifica-o no teu site

Analisa o teu site grátis e vê se esta e outras 44 verificações passam, com um fix prompt por cada problema.

Analisar o meu site grátis

Do blog

Verificações relacionadas