Chave secreta de API no navegador: por que nunca no front-end

GuiaUNIFOKAL5 min de leituraProduto e integração
Ver em Markdown

Tudo o que chega ao navegador pode ser lido por quem usa a página. Por que a chave secreta de uma API de verificação fica só no servidor, o que vai no lugar dela e o que fazer quando ela vaza.

Neste artigo, 5 seções

Integrar uma API de verificação de identidade começa por uma chave secreta, e a tentação de quem está com pressa é colocá-la no código do front-end e chamar a API direto do navegador. Funciona no primeiro teste, e o custo aparece depois. A resposta curta: todo arquivo que o navegador baixa pode ser lido por quem abre a página, inclusive a variável de ambiente que o processo de build embutiu no pacote; a chave secreta autentica o seu sistema, não a pessoa, e com ela qualquer um cria sessões e lê resultados em seu nome. O desenho certo é o servidor criar a sessão com a chave secreta e entregar ao navegador só uma credencial de escopo curto, que habilita uma única verificação.

  • O OWASP ASVS 5.0 manda que segredos não fiquem "in application source code or included in build artifacts" (requisito 13.3.1).
  • O OWASP API Security Top 10 2023 lembra que chave de API autentica o cliente da API, não o usuário.
  • No navegador vai uma credencial de uma sessão só, com prazo curto, que não abre outras sessões nem a conta.
  • Quando a chave vaza, a resposta é revogar e trocar, e a revogação precisa cortar também o que a chave já emitiu.

Por que o navegador não guarda segredo

O navegador executa o código que o servidor manda. Tudo o que está nesse código, inclusive uma constante com a chave, chega à máquina de quem abriu a página e pode ser visto nas ferramentas de desenvolvedor, no pacote JavaScript baixado ou no tráfego de rede. Não importa se a chave veio de uma variável de ambiente: se o build a colocou no pacote do front-end, ela está no artefato publicado.

O padrão de verificação de segurança de aplicações da OWASP, o ASVS na versão 5.0, diz isso como requisito. No capítulo de configuração, o 13.3.1 pede uma solução de gestão de segredos para criar, guardar, controlar acesso e destruir segredos do back-end, entre eles "API keys", e conclui: "Secrets must not be included in application source code or included in build artifacts." O capítulo de proteção de dados acrescenta, no 14.3.3, que o armazenamento do navegador não deve conter dado sensível, com exceção de tokens de sessão.

O que a chave secreta autentica

O OWASP API Security Top 10 2023, na categoria API2, de autenticação quebrada, faz uma distinção que organiza o desenho: "OAuth is not authentication, and neither are API keys", e "API keys should not be used for user authentication. They should only be used for API clients authentication." A chave secreta da API de verificação identifica o seu sistema como cliente da API. Quem a tem é tratado como o seu sistema.

o que um atacante faz com cada tipo de credencial que chega ao navegador (leitura da casa)
CredencialOnde deve viverSe vazar, o atacante consegueRaio do dano
Chave secreta da APISó no servidorCriar sessões, ler resultados e eventos, gastar saldo em seu nomeA conta inteira, até a revogação
Credencial de sessão de escopo curtoNo navegador, para uma verificaçãoAbrir a captura daquela verificação, dentro do prazoUma sessão
Chave publicável, quando o fornecedor tem umaNo navegadorO que a documentação do fornecedor permitir a elaDefinido pelo escopo

O desenho certo nasce dessa tabela: o navegador só recebe credencial cujo vazamento afeta uma sessão. A comparação entre embutir um widget e chamar a API direto, e onde vivem as credenciais em cada caso, está no pilar widget ou API pura.

O desenho certo: o servidor cria, o navegador captura

O fluxo seguro tem três passos:

  1. O navegador avisa o seu servidor que a pessoa quer se verificar.
  2. O seu servidor chama a API com a chave secreta, cria a sessão e devolve ao navegador só o identificador dela.
  3. O navegador usa esse identificador para abrir a captura, e o resultado chega ao seu servidor pelo webhook, não pelo navegador.

Na UNIFOKAL, a documentação de autenticação diz isso com todas as letras: a chave secreta "é só server-side", e o front recebe do seu back-end "apenas o sessionId", escopado a uma única sessão, de uso curto e com prazo de validade. Expor esse identificador por engano não compromete outras sessões nem a conta. O resultado vale pelo webhook assinado, porque uma resposta lida no navegador pode ser forjada por quem controla o navegador.

Um "proxy" no seu servidor que só repassa ao fornecedor qualquer chamada vinda do navegador, sem decidir o que é permitido, devolve o problema: o atacante não vê a chave, mas usa o seu proxy como se a tivesse. O servidor precisa criar só o que a regra do seu produto permite, para a pessoa autenticada no seu sistema.

Quando a chave vaza

A leitura da casa para o vazamento, em quatro passos:

  1. Revogar. A chave exposta deixa de valer imediatamente, sem esperar a investigação.
  2. Cortar o que ela emitiu. Sessões e links criados com a chave e ainda não usados também caem. Na UNIFOKAL, revogar a chave corta "o que ela emitiu e ainda não começou": o link de verificação ainda não usado deixa de abrir e a sessão que o titular ainda não enviou deixa de valer.
  3. Trocar com janela, quando não é vazamento. Na troca planejada, as duas chaves valem por um tempo; o ASVS pede, no 13.3.4, que os segredos tenham expiração e rotação definidas na documentação. O procedimento sem derrubar a integração está em rotação de chave e segredo de webhook.
  4. Procurar a origem. Repositório, pacote publicado, log, ferramenta de suporte. Enquanto a origem não fecha, a chave nova vaza do mesmo jeito.

Uma checagem simples no processo de entrega pega o erro antes da produção: procurar o prefixo da chave secreta no pacote do front-end gerado pelo build. Se aparecer, o build falha.

Fontes citadas

  • OWASP, Application Security Verification Standard 5.0.0, capítulo V13, requisitos 13.3.1 e 13.3.4, e capítulo V14, requisito 14.3.3, no repositório oficial
  • OWASP, API Security Top 10 2023, API2:2023 Broken Authentication, em owasp.org