Gerador de hash SRI
Informe o endereço de um script ou de uma folha de estilo e receba a tag de volta com o atributo integrity, além de uma verificação de que o navegador vai aceitá-la. Você também pode gerar o hash de um arquivo ou de código colado, e essa parte fica no seu aparelho.
Ou calcule o hash de um arquivo no seu dispositivo
Para um arquivo que ainda não está online, ou que você prefere guardar para si. O hash é calculado pelo seu navegador: o que você soltar ou colar aqui não é enviado para nós.
Escolha um arquivo, ou solte um em qualquer lugar desta caixa.
Um lacre no código que você não hospeda
Quando sua página carrega uma biblioteca de uma CDN, você dá ao servidor de um estranho o direito de executar código diante dos seus visitantes. Se esse servidor for invadido, ou se o projeto mudar de dono, o mesmo endereço pode começar a devolver outra coisa, como um clonador de cartão, um minerador de criptomoeda ou um redirecionamento. Sua página continua funcionando e você nunca percebe. Isso já aconteceu com bibliotecas reais usadas por centenas de milhares de sites.
Subresource Integrity (SRI) é o recurso do navegador que trata disso. Você acrescenta à tag uma impressão digital do arquivo que revisou, calculada com uma função de hash como SHA-384. O navegador baixa o arquivo, calcula a impressão digital de novo e só executa o arquivo se as duas baterem. Mude um único byte e a impressão digital sai diferente, então o arquivo é bloqueado.
<script src="https://cdn.example.com/lib@2.4.1/lib.min.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>O que esta página calcula e verifica
Quando você informa um endereço, nosso servidor baixa o arquivo uma vez e envia um cabeçalho Origin, como o navegador faz para uma tag com crossorigin. O hash é calculado sobre o corpo depois da decodificação gzip ou Brotli, que é exatamente o que o navegador usa. Você recebe a tag completa com SHA-384, e também os valores SHA-256 e SHA-512.
Um hash correto não garante que a tag vai funcionar, então lemos mais quatro coisas na resposta:
| Verificação | Por que importa |
|---|---|
Access-Control-Allow-Origin | Para um arquivo de outra origem, o navegador precisa dessa permissão antes de poder comparar os bytes. Sem ela, uma tag com integrity falha sempre. Cabeçalho ausente: erro. |
| Versão no endereço | /3.7.1/ ou @5.3.3 devolve o mesmo arquivo para sempre. @latest, @5, um nome de branch, uma versão só em ?ver= ou nenhuma versão significa que o arquivo pode mudar, e a página quebra quando ele mudar. Aviso. |
Cache-Control | Uma validade de um ano ou immutable indica um arquivo congelado. Uma validade de menos de um dia indica que o endereço foi feito para mudar. |
Content-Type | Scripts precisam chegar como JavaScript e folhas de estilo como text/css. Visualizadores de arquivo bruto costumam enviar text/plain, que os navegadores recusam. |
Uma pequena lista de endereços é recusada de cara: carregadores de analytics e de gerenciador de tags, scripts de pagamento, folhas de estilo de fontes montadas para cada navegador. Os donos reescrevem esses arquivos no mesmo lugar, então pôr um hash em um deles é marcar a data de uma pane.
A segunda caixa calcula o hash de um arquivo que você soltar, ou de código que você colar, com o próprio crypto.subtle do navegador. Nada é enviado.
Usar a tag sem quebrar a página
- Fixe a versão primeiro. Troque
library@latestpela versão exata que você testou e depois gere o hash para esse endereço. - Mantenha
crossorigin="anonymous". Sem isso, o navegador faz uma requisição que não tem permissão de inspecionar e bloqueia o arquivo. - Carregue a página e abra o console. Uma divergência aparece ali como uma verificação de integridade que falhou, com o nome do arquivo.
- Atualize de propósito. Uma nova versão da biblioteca exige um novo endereço e um novo hash. Dá um pouco de trabalho, e é justamente essa a ideia: nada muda até você decidir.
Para arquivos no seu próprio domínio, o SRI ajuda pouco contra um invasor que já controla o seu servidor, já que ele pode editar a página e o hash juntos. Ainda assim é útil quando páginas e arquivos são servidos por sistemas diferentes, por exemplo o HTML pelo seu servidor e os arquivos pelo seu próprio bucket de CDN.
Limites: uma requisição, de um só lugar. Um servidor pode mandar outros bytes para outro navegador ou região, e não verificamos se o arquivo é seguro, só se é o mesmo. Um atributo integrity cobre o arquivo em que está, não os scripts que esse arquivo carrega depois.
Perguntas frequentes
Qual hash devo usar: sha256, sha384 ou sha512?
Os navegadores aceitam os três e nenhum é considerado fraco. SHA-384 é a convenção. É o que as CDNs publicam e o que a maioria das documentações mostra, então use-o, a não ser que uma política diga outra coisa.
Por que meu script para de carregar depois que adiciono integrity?
Há três causas comuns. O servidor não envia Access-Control-Allow-Origin, ou falta crossorigin="anonymous" na tag. O arquivo mudou desde que o hash foi calculado, porque o endereço não está preso a uma versão. Ou algo entre o servidor e o navegador reescreve o arquivo, como um proxy que minifica scripts. O console do navegador diz qual é o caso.
Posso usar SRI com Google Fonts, Google Analytics ou Stripe?
Não. Esses endereços devolvem conteúdo que os donos atualizam quando querem, e a folha de estilo das fontes muda de um navegador para outro. Um hash fixo os bloquearia na próxima mudança. Restrinja-os com uma Content-Security-Policy em vez disso.
O hash muda se o servidor comprimir o arquivo?
Não. O navegador verifica o arquivo depois da descompressão, então gzip, Brotli e zstd não fazem diferença. Minificar ou reformatar o arquivo, sim, muda o hash.
Imagens e fontes aceitam o atributo integrity?
Hoje não. Os navegadores o aplicam em <script> e em <link> para folhas de estilo, preloads e module preloads. Em outros elementos ele é ignorado.
Como calculo o mesmo hash na linha de comando?
Com OpenSSL: openssl dgst -sha384 -binary file.js | openssl base64 -A, depois coloque sha384- na frente do resultado.