Também disponível em: English · Español · Français · العربية
Gerador de hash SRI
Valores integrity calculados no seu navegador, com a etiqueta inteira incluindo o atributo que toda a gente esquece, e um verificador para o que já tem.
O que é o Subresource Integrity
Quando uma página carrega um script do servidor de outra pessoa — uma CDN, um fornecedor de estatísticas, um serviço de tipos de letra — está a confiar-lhe tudo. Os bytes que vierem são executados com todos os privilégios da sua página. Se esse servidor for comprometido, ou simplesmente servir outra coisa um dia, os seus visitantes executam-na.
O Subresource Integrity é a solução. Põe-se um resumo criptográfico do ficheiro esperado num atributo integrity da etiqueta script ou link. O navegador descarrega o ficheiro, resume-o e recusa-se a executá-lo se o resumo não corresponder. Uma CDN comprometida passa a partir-lhe a página em vez de se apoderar dela, o que é uma falha bem melhor.
O atributo tem a forma sha384- seguido de uma cadeia em base64. Esta página calcula essa cadeia a partir de um ficheiro que escolha ou de texto que cole, dá-lhe a etiqueta completa para copiar e, no outro modo, pega num atributo que já tenha e diz-lhe se um navegador o aceitaria.
Como usar
- Dê-lhe os bytes exactos do ficheiro. Escolha o ficheiro local ou cole o conteúdo. O resumo é dos bytes tal como são servidos, portanto uma única mudança de linha no fim altera a resposta — é por isso que gerar a partir de uma cópia que o seu editor reformatou não vai corresponder.
- Escolha o algoritmo e copie a etiqueta, não só o valor. O sha384 é o habitual e é o que os exemplos da própria norma usam. A etiqueta gerada inclui o crossorigin, que não é opcional para um ficheiro de outra origem.
- Ou passe a Verificar para testar um atributo que já tem. Cole o atributo integrity ao lado do ficheiro e recebe um veredicto, o algoritmo que o navegador consultaria de facto, e a lista das expressões que foram ignoradas.
Um segundo algoritmo substitui o primeiro, não o reforça
É esta a regra à volta da qual a página foi construída, e quase ninguém a conhece. Quando um atributo integrity lista várias expressões de resumo, o navegador não as verifica todas nem aceita uma correspondência com qualquer uma delas. A norma diz que escolhe a função de resumo mais forte da lista e usa só essa, descartando todas as mais fracas antes de qualquer comparação. A ordem é fixa: o sha256 é mais fraco do que o sha384, que é mais fraco do que o sha512.
A consequência é afiada. Se puser um sha256 correcto e um sha512 mal escrito, o seu ficheiro é bloqueado — o resumo correcto é deitado fora sem ser lido. Se puser um sha256 mal escrito e um sha384 correcto, o ficheiro carrega perfeitamente e o resumo partido nunca contou. Acrescentar um segundo algoritmo parece defesa em profundidade e não é nada disso; é uma substituição, e transfere em silêncio toda a sua confiança para o que for mais forte.
Há um caso em que vários resumos significam mesmo qualquer um destes, e é o útil: várias expressões com o mesmo algoritmo. É assim que se permitem duas versões válidas de um ficheiro durante uma implantação, e o navegador aceita uma correspondência com qualquer delas. Portanto sha384-A sha384-B é uma verdadeira alternativa, e sha256-A sha512-B não é.
Quando verifica aqui um atributo, tudo o que essa regra descartar é listado à parte, porque a regra é invisível no próprio atributo e um veredicto sem ela seria um mistério.
Outras duas coisas que o partem em silêncio
A primeira é o crossorigin em falta. Os pedidos a outra origem que levam integrity são obrigados a usar CORS, portanto uma etiqueta script que aponta para uma CDN com atributo integrity e sem crossorigin não carrega de todo — e a falha parece exactamente um resumo errado, o que manda as pessoas recalcular um valor que estava certo desde o início. Todas as etiquetas que esta página gera incluem crossorigin="anonymous". Implica também que a própria CDN tem de enviar cabeçalhos CORS permissivos; se não o fizer, não pode usar SRI com ela.
A segunda é como o valor é calculado. A norma diz para aplicar o algoritmo aos bytes e depois codificar o resultado em base64 — base64 do resumo cru. Muitíssimas tentativas caseiras resumem primeiro para uma cadeia hexadecimal e codificam isso, o que produz um valor com ar correcto que nunca corresponde. Os comprimentos denunciam-no: um resumo sha384 são 48 bytes e codifica-se em 64 caracteres base64, ao passo que o base64 da sua forma hexadecimal de 96 caracteres são 128. O gerador mostra os dois lado a lado para que a diferença se veja em vez de ser afirmada.
Mais uma, menos dramática: um navegador que não reconheça um algoritmo ignora essa expressão em vez de rejeitar o ficheiro. É deliberado, e é o que lhe permite acrescentar hoje um algoritmo futuro sem partir nada — mas significa também que um atributo cheio de algoritmos que ninguém suporta não protege absolutamente nada.
Limites honestos
Esta página não consegue descarregar um URL por si. Um navegador não tem permissão para ler de um script um ficheiro de outra origem a não ser que esse servidor consinta com CORS — a mesma regra que torna o crossorigin obrigatório na etiqueta. Portanto escolhe o ficheiro local ou cola o conteúdo, e qualquer ferramenta que pareça descarregar o URL por si está a fazê-lo num servidor, o que significa confiar-lhe esse descarregamento. Fazê-lo localmente é ao mesmo tempo a opção honesta e a privada.
O resumo cobre os bytes e mais nada. Não lhe diz que o ficheiro é seguro, nem bem escrito, nem de quem julga — apenas que não mudou desde que tirou o resumo. Se resumir um ficheiro comprometido, o SRI garante-lhe fielmente o ficheiro comprometido.
Também o prende a uma versão. Qualquer actualização do ficheiro, incluindo uma correcção de segurança que o fornecedor publique, falha a verificação até regenerar o valor. É essa a troca que o SRI faz, e é por isso que assenta muito melhor em URLs versionados do que num latest flutuante.
Por fim, o integrity aplica-se a scripts e folhas de estilo. Não é um mecanismo geral para imagens, tipos de letra ou pedidos fetch, portanto uma etiqueta gerada aqui pertence a um elemento script ou link e a mais lado nenhum.
Porque é grátis
Porque não custa nada manter. O resumo é feito no seu navegador através da Web Crypto API que já lá está; o ficheiro que escolher não sai da sua máquina, nada é enviado e nenhum servidor o vê.
Nem conta, nem registo, nem nada guardado atrás de um. As regras saem da própria norma do Subresource Integrity, e as verificações que as confirmam usam os resumos de exemplo que a norma publica, confrontados com uma implementação diferente.