FlowingDev

SRI, explicado: a impressão digital dos assets do seu site

Aprenda como a Subresource Integrity (SRI) usa hashes criptográficos para proteger seu site contra scripts e estilos maliciosos servidos por CDNs de terceiros.

Testar a ferramenta: Gerador de Hash SRI

Em uma frase

Subresource Integrity (SRI) é um recurso de segurança que permite aos navegadores verificar se os arquivos que eles buscam de fontes externas, como CDNs, não foram adulterados secretamente.

O problema que ele resolve

Imagine a cena: você está construindo uma nova e elegante aplicação web. Para deixá-la bem rapidinha, você usa uma Content Delivery Network (CDN) para servir bibliotecas comuns como React, Vue, ou até mesmo algumas fontes estilosas. Essa é uma prática padrão. Seus usuários têm uma experiência mais rápida porque o arquivo provavelmente já está em cache no navegador deles por terem visitado outro site, ou é servido de um servidor fisicamente mais próximo a eles. Todo mundo sai ganhando, certo?

Quase. Mas você acabou de introduzir um elemento massivo de confiança. Você está confiando que o provedor de CDN sempre servirá o arquivo exato que você pretendia. E se essa CDN for hackeada? Um invasor poderia substituir o amigável e útil react.min.js por uma versão maliciosa: react.min.js-com-um-minerador-de-cripto-e-ladrão-de-senhas.

De repente, esse código malicioso está rodando no seu site, com a total confiança dos navegadores dos seus usuários. Ele pode sugar credenciais de login, desfigurar suas páginas ou recrutar seus visitantes para uma botnet. Este é um ataque clássico de supply-chain (cadeia de suprimentos), e é aterrorizante porque você não fez nada de errado no seu próprio servidor. Você apenas confiou na parte errada na hora errada.

Antes do SRI, não havia um mecanismo nativo do navegador para se defender contra isso. Os desenvolvedores usavam gambiarras, mas eram desajeitadas. O SRI foi criado pela W3C para resolver este problema específico de frente. Ele fornece uma maneira simples e padronizada de dizer ao navegador: "Ei, vá buscar este script, mas antes de executá-lo, tenha certeza absoluta de que é o que estou esperando. Se tiver um único byte de diferença, jogue-o no lixo e me avise."

Como funciona por debaixo dos panos

O SRI é um casamento inteligente entre um atributo HTML simples e alguns princípios criptográficos sérios. Vamos destrinchar isso.

O atributo integrity

A mágica começa com um novo atributo que você pode adicionar às suas tags <script> e <link>. Ele se chama, apropriadamente, integrity.

<script
  src="https://code.jquery.com/jquery-3.6.0.min.js"
  integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3"
  crossorigin="anonymous"></script>

Este atributo contém uma string com duas partes: um prefixo de algoritmo de hash (aqui, sha384-) e um hash criptográfico codificado em Base64. Esta é a "impressão digital" do arquivo que você espera receber.

O Hash: Uma Impressão Digital

Uma função de hash criptográfico é um algoritmo matemático que pega uma entrada (como todo o conteúdo de um arquivo JavaScript) e produz uma string de caracteres curta e de tamanho fixo, chamada de hash. Pense nisso como um checksum superpotente.

Esses hashes têm algumas propriedades cruciais:

  • Determinísticos: O mesmo arquivo de entrada sempre produzirá o mesmo hash exato.
  • Efeito Avalanche: Mude apenas um único caractere no arquivo de entrada — adicione um espaço, mude o nome de uma variável — e o hash resultante será completamente diferente e irreconhecível.
  • Unidirecional (One-way): É praticamente impossível reverter o processo. Você não pode pegar o hash e descobrir qual era o conteúdo original do arquivo.

O padrão SRI suporta três algoritmos de hash seguros: SHA-256, SHA-384 e SHA-512. O número se refere ao comprimento em bits do hash, e maior geralmente significa mais forte. SHA-384 é uma ótima escolha geral.

Então, quando você está prestes a linkar para um arquivo de CDN, você primeiro gera seu hash. Você está essencialmente tirando uma foto do arquivo naquele momento e dizendo ao navegador: "É assim que o verdadeiro jquery-3.6.0.min.js se parece."

O atributo crossorigin

Viu aquele crossorigin="anonymous" no exemplo? Não está aí só de enfeite; é obrigatório. Para que um navegador busque um recurso de uma origem diferente (por exemplo, seu site meu-app.com buscando um script de code.jquery.com) e inspecione seu conteúdo para a verificação do SRI, ele precisa de permissão via Cross-Origin Resource Sharing (CORS).

Definir crossorigin="anonymous" diz ao navegador para fazer a requisição sem enviar quaisquer credenciais do usuário, como cookies ou cabeçalhos de autenticação HTTP. Isso é indispensável para segurança e privacidade. Se você esquecer este atributo, o navegador se recusará a realizar a verificação de integridade e simplesmente bloqueará o carregamento do recurso, levando a um site quebrado.

Juntando tudo: A lista de verificação do navegador

Quando um navegador encontra uma tag com um atributo integrity, ele segue este protocolo rigoroso:

  1. Ele vê a tag <script> e anota os atributos src, integrity e crossorigin.
  2. Ele envia uma requisição para o arquivo na URL src. Graças ao crossorigin, esta é uma requisição CORS.
  3. O arquivo é baixado.
  4. Crucialmente, antes de executar qualquer coisa, o navegador calcula seu próprio hash do conteúdo do arquivo baixado, usando o mesmo algoritmo especificado no atributo integrity (por exemplo, sha384).
  5. Em seguida, ele compara seu hash recém-calculado com o hash que você forneceu no atributo.
  6. Se eles corresponderem: Uhul! O arquivo é autêntico. O navegador executa o script ou aplica a folha de estilo.
  7. Se eles não corresponderem: ALERTA VERMELHO! O navegador assume que o arquivo foi adulterado. Ele descarta completamente o arquivo e não o executa. Em seguida, ele dispara um erro Failed to find a valid digest no console do desenvolvedor. Seu site pode parecer quebrado (por exemplo, um gráfico ou fonte ausente), mas você desviou de uma bala com sucesso.

Histórias do mundo real

O Dashboard de Analytics Desfigurado

Uma equipe de marketing dependia de um dashboard que usava uma biblioteca de gráficos de terceiros, puxada de uma CDN de nicho, para visualizar os dados de suas campanhas. O desenvolvedor, que tinha acabado de ler sobre as melhores práticas de segurança, adicionou hashes de SRI à tag <script> da biblioteca. Em uma manhã de segunda-feira, a CDN sofreu um breve comprometimento. Um invasor substituiu a popular biblioteca de gráficos por um script que apenas exibia uma cara gigante e zombeteira em arte ASCII.

Quando a equipe de marketing carregou o dashboard, os gráficos estavam quebrados. Eles viam caixas vazias. Eles ligaram para o TI, irritados. O desenvolvedor verificou o console do navegador e viu o belo, belo erro de validação do SRI. O navegador detectou o arquivo modificado, recusou-se a executá-lo e impediu a desfiguração. Em vez de um grande incidente de segurança e executivos em pânico, foi uma investigação de 15 minutos que terminou com a troca temporária para uma CDN diferente.

Lição: O SRI transforma uma catástrofe de segurança em potencial em um problema de disponibilidade controlável.

O Minerador de Cripto Sorrateiro

Uma popular e leve biblioteca de utilitários JavaScript hospedada em uma CDN gratuita era a favorita dos desenvolvedores independentes. Um invasor obteve acesso à CDN e modificou o arquivo da biblioteca, adicionando algumas linhas de código ofuscado que disparavam um minerador de criptomoedas em WebAssembly. O tamanho do arquivo mal mudou e as funções principais da biblioteca ainda funcionavam perfeitamente.

Sites que usavam a biblioteca sem SRI de repente começaram a fazer com que os laptops de seus usuários disparassem as ventoinhas e drenassem as baterias. Os usuários reclamaram de lentidão, mas era difícil de diagnosticar. Os próprios sites pareciam normais. No entanto, os sites que implementaram o SRI estavam imunes. Seus navegadores bloquearam o script modificado e, embora as funções de utilitário tenham quebrado, as CPUs de seus usuários estavam seguras.

Lição: O SRI não pega apenas desfigurações óbvias, mas também ataques sutis e parasitas que podem prejudicar a reputação do seu site.

A Atualização de Fonte Esquecida

Um designer insistiu em usar uma versão específica de uma fonte de uma fundição de fontes de terceiros, servida via CDN deles. O desenvolvedor copiou diligentemente a tag <link>, completa com seu hash de SRI. O site foi lançado e parecia ótimo. Seis meses depois, a fundição atualizou o arquivo da fonte para adicionar novos símbolos de moeda e melhorar o kerning. Foi uma atualização legítima e útil.

De repente, o texto do site reverteu para a feia e padrão Arial. O desenvolvedor ficou perplexo até verificar o console e ver o erro de SRI. O navegador estava bloqueando corretamente o novo arquivo de fonte modificado porque seu hash não correspondia mais ao antigo no HTML. O "ataque" foi apenas uma atualização benigna, mas o SRI fez seu trabalho. A correção foi simples: gerar um novo hash para a fonte atualizada e implantar a alteração.

Lição: O SRI impõe um versionamento estrito. Ele protege você de alterações maliciosas e de atualizações inesperadas de upstream, forçando você a ser intencional sobre os assets que utiliza.

Erros e armadilhas comuns

  • Esquecer crossorigin="anonymous". Este é o erro nº 1. Sem ele, o navegador não tem permissão CORS para inspecionar o recurso, então, por segurança, ele simplesmente o bloqueia. Nenhuma verificação de integridade acontece. Seu script ou estilo simplesmente não carrega.
  • Fazer o hash da coisa errada. Você deve fazer o hash do conteúdo exato do arquivo que o navegador recebe. Não faça o hash de uma versão local e não comprimida de um script se você estiver linkando para a versão minificada da CDN. Não faça o hash da própria string da URL. Você precisa do hash do corpo do arquivo.
  • Usar algoritmos de hash fracos. MD5 e SHA-1 têm vulnerabilidades conhecidas e não devem ser usados para fins de segurança. A especificação exige que os navegadores suportem pelo menos SHA-256, SHA-384 e SHA-512. Fique com esses.
  • Não atualizar o hash após uma atualização legítima. SRI é uma feature, não um bug. Se o arquivo para o qual você está linkando for atualizado por qualquer motivo, você deve gerar um novo hash de integridade e atualizar seu atributo integrity no HTML. A falha em fazer isso resultará no bloqueio do recurso.
  • Achar que protege seu próprio servidor. O SRI foi projetado para validar recursos de terceiros. Se um invasor comprometeu seu servidor o suficiente para alterar seus arquivos HTML, ele pode simplesmente alterar o hash do SRI para corresponder ao script malicioso dele. Ele não oferece nenhum benefício para recursos da mesma origem (same-origin).

Por que isso deve estar no seu radar

Você deve pensar em SRI toda santa vez que escreve um <script src="..."> ou <link rel="stylesheet" href="..."> que aponta para um domínio que você não controla.

É uma peça fundamental da segurança web moderna. Em um mundo construído sobre NPM, CDNs e uma teia complexa de dependências de terceiros, sua cadeia de suprimentos (supply chain) é uma superfície de ataque massiva. O SRI é uma das ferramentas mais simples e eficazes para fortalecer essa superfície. É sua primeira linha de defesa contra um CDN comprometido. Combinado com uma Content Security Policy (CSP), ele fornece uma proteção robusta e em camadas.

Adicionar o SRI leva alguns segundos extras quando você adiciona um recurso, mas pode te poupar de um mundo de dor no futuro. Ele transforma um exploit silencioso e perigoso em uma falha barulhenta e segura.

Vá mais a fundo

Teoria feita. Hora de pôr a mão na massa — 100% no seu navegador.

Testar a ferramenta: Gerador de Hash SRI