Integridade de sub-recursos (SRI)

O que é integridade de sub-recursos?

SRI é uma especificação da W3C que permite aos desenvolvedores web garantir que os recursos hospedados em servidores de terceiros não foram adulterados. Seu uso é recomendado como boa prática, sempre que as bibliotecas são carregadas de uma fonte de terceiro.

Qual a diferença entre SRI e HTTPS?

O HTTPS garante que a conexão entre o navegador e o servidor seja segura. O próprio recurso ainda pode ser modificado no lado do servidor por um invasor para incluir conteúdo malicioso, mas ainda pode ser servido com um certificado válido. O SRI, por outro lado, garante que um recurso não mudou desde que o hash foi criado.

Por que incluir crossorigin=”anonymous”?

Quando a solicitação não está na mesma origem, o atributo crossorigin deve estar presente para a verificação da integridade do arquivo. Sem este atributo, o navegador informará fail-open, o que significa que carregará o recurso como se o atributo de integridade não tivesse sido definido, perdendo efetivamente toda a segurança que o SRI traz em primeiro lugar.
O crossorigin="anonymous" resulta que nenhuma credencial é enviada ao site de origem que hospeda o conteúdo. No entanto, ele enviará um cabeçalho HTTP Origin.Se o servidor negar a inclusão do recurso (por não definir o cabeçalho HTTP Access-Control-Allow-Origin), o recurso não será usado pelo navegador.

O Atributo de integrity

Podemos instruir o navegador a verificar a integridade do conteúdo carregado externamente, incluindo o atributo integrity nas tags <script> ou <link>. Este atributo conterá as versões codificadas em base64 dos hashes criptográficos que esperamos para esse ativo específico.
Exemplos:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js" integrity="sha256-ivk71nXhz9nsyFDoYoGf2sbjrR9ddh+XDkCcfZxjvcM=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" integrity="sha256-8EtRe6XWoFEEhWiaPkLawAD1FkD9cbmGgEy6F46uQqU=" crossorigin="anonymous">

Pode ser utilizado mais de um tipo de hashes, como por exemplo o hash SHA256 junto com o SHA512, deixando para o navegador selecionar qual algoritmo de hash é mais forte e compatível com a verificação de integridade.
Exemplos:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js" integrity="sha256-ivk71nXhz9nsyFDoYoGf2sbjrR9ddh+XDkCcfZxjvcM= sha512-7aMbXH03HUs6zO1R+pLyekF1FTF89Deq4JpHw6zIo2vbtaXnDw+/2C03Je30WFDd6MpSwg+aLW4Di46qzu488Q==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" integrity="sha256-8EtRe6XWoFEEhWiaPkLawAD1FkD9cbmGgEy6F46uQqU= sha512-/5KWJw2mvMO2ZM5fndVxUQmpVPqaxZyYRTMrXtrprsyQ2zM0o0NMjU02I8ZJXeBP trmrPO4IAyCCRsydG0BJoQ==" crossorigin="anonymous">

Além disso, também é importante notar que podem ser especificados vários hashes do mesmo tipo, caso você precise que um conteúdo diferente seja servido para a solicitação.

Ferramentas para gerar hashes SRI

Existem duas formas fáceis de criar os hashes dos seus objetos.

O SRI Hash Generator é uma ferramenta online que você pode usar para gerar hashes SRI.

Caso prefira gerar manualmente via linha de comando, é necessário utilizar o OpenSSL, com o seguinte comando:

cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A

Pode ser utilizado também com shasum usando o comando:

shasum -b -a 384 FILENAME.js | awk '{ print $1 }' | xxd -r -p | base64

  • O pipe xxd pega a saída hexadecimal shasume a converte em binária
  • A etapa awk do pipe é necessária porque o shasum vai passar o nome do arquivo hasheado em sua saída xxd. Isso pode ter consequências desastrosas se o nome do arquivo tiver caracteres hexadecimais válidos, porque o xxd também decodificará isso e passará para base64.

No Windows, é possível criar uma ferramenta para geração dos hashes SRI com o seguinte código:

@echo off
set bits=384
openssl dgst -sha%bits% -binary %1% | openssl base64 -A > tmp
set /p a= < tmp
del tmp
echo sha%bits%-%a%
pause

Para usar o código:

  1. Salve esse código como sri-hash.bat na pasta SendTo do Windows em seu ambiente (C:\Users\USER\AppData\Roaming\Microsoft\Windows\SendTo).
  2. Clique com o botão direito em um arquivo no Explorer, selecione ‘Enviar Para’ e selecione sri-hash. Você verá o valor do integrity em uma caixa de comando.
  3. Selecione o valor de integrity e clique com o botão direito para copiá-lo para a área de transferência.
  4. Pressione qualquer tecla para fechar a caixa de comando.

O comando wget faz download do arquivo. A partir daí, o comando car produz o arquivo que é canalizado para o OpenSSL que irá executá-lo por meio do hash SHA256 e fornecer o resumo na forma binária. Isso é então canalizado para o OpenSSL novamente para codificar a saída em base64. A string resultante é o valor do atributo integrity.

Atributo crossorigin

O 'crossorigin' instrui o navegador a fazer uma solicitação habilitada para CORS de forma ativa. O compartilhamento de recursos crossorigin. Podem ser passador 2 valores para este atributo que são anonymous e use-credentials, a diferença entre eles é que o primeiro é usado porque é feito através de uma solicitação HTTP simples, sem envio de credenciais, ou seja, sem cookies, sem certificados e sem a autenticação básica do HTTP.

Como os navegadores lidam com o SRI

Os navegadores lidam com SRI fazendo o seguinte:

  1. Quando um navegador encontra um elemento <script> ou <link> com o atribuito integrity, antes de executar o script ou baixar a folha de estilos especificada, o navegador primeiro compara o script ou a folha de estilos ao valor do hash esperado fornecido pelo integrity;

    Observação: para verificação de SRI de um recurso servido de uma origem diferente do documento no qual está incorporado, os navegadores também verificam o recurso usando CORS, para garantir que a origem que atende o recurso permite que ele seja compartilhado com a origem solicitante.

  2. Se o script ou folha de estilo não corresponder ao valor associado de integrity o navegador deve se recusar a executar o script ou aplicar a folha de estilo e, em vez disso, deve retornar um erro de rede indicando que a busca desse script ou folha de estilo falhou.

Navegadores compatíveis

Os seguintes navegadores desktop são compatíveis a partir das seguintes versões:
Chrome 45+, Edge, 17+, Firefox 43+, Opera, Safari 11.1+.

Os seguintes navegadores mobile são compatíveis a partir das seguintes versões:
WebView Android 45+, Chrome Android 45+, Firefox for Android 43+, Safari IOS 11.3+, Samsung Internet 5.0+.

O Internet Explorer não tem compatibilidade, e o Opera Android não se sabe se possui compatibilidade.

18