Subresource Integrity (SRI): verificando integridade de assets externos
1. Introdução ao Subresource Integrity (SRI)
O Subresource Integrity (SRI) é um mecanismo de segurança do navegador que permite verificar se um recurso externo (como uma biblioteca JavaScript ou folha de estilo CSS) foi carregado sem modificações maliciosas. Surgiu como resposta aos crescentes ataques à cadeia de suprimentos (supply chain attacks), onde invasores comprometem CDNs ou repositórios públicos para injetar código malicioso em bibliotecas amplamente utilizadas.
Diferente de checksums tradicionais ou assinaturas digitais, o SRI opera inteiramente no navegador, sem necessidade de infraestrutura adicional de chaves ou certificados. Enquanto checksums validam integridade durante o download e assinaturas digitais verificam autenticidade, o SRI foca exclusivamente em garantir que o recurso baixado corresponde exatamente ao hash esperado, protegendo contra modificações não autorizadas no caminho entre o servidor e o cliente.
2. Funcionamento técnico do SRI
O SRI é implementado através do atributo integrity nas tags <script> e <link>. O formato segue o padrão:
algoritmo-hash_base64
Os algoritmos suportados são SHA-256, SHA-384 e SHA-512. O processo de verificação segue estas etapas:
- O navegador baixa o recurso externo
- Calcula o hash do conteúdo usando o algoritmo especificado
- Compara o hash calculado com o valor do atributo
integrity - Se coincidirem, executa o recurso; caso contrário, bloqueia o carregamento
Exemplo prático:
<script src="https://cdn.example.com/script.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
O atributo crossorigin é obrigatório para recursos de origens diferentes, pois o navegador precisa de permissão CORS para ler o conteúdo completo do recurso e calcular o hash.
3. Gerando hashes SRI corretamente
A geração de hashes pode ser feita via linha de comando com ferramentas nativas do sistema operacional. Exemplos práticos:
Usando OpenSSL:
openssl dgst -sha384 -binary arquivo.js | openssl base64 -A
Usando shasum:
shasum -b -a 384 arquivo.js | awk '{ print $1 }' | xxd -r -p | base64
Para recursos já hospedados em CDNs, é possível baixar o arquivo e calcular o hash localmente:
curl -s https://cdn.example.com/library.js | openssl dgst -sha384 -binary | openssl base64 -A
Geradores online como srihash.org são práticos, mas devem ser usados com cautela — nunca insira hashes de recursos críticos em sites desconhecidos. Prefira ferramentas open-source ou extensões de navegador confiáveis.
4. Implementando SRI em assets estáticos e CDNs
A aplicação prática do SRI em bibliotecas populares segue o mesmo princípio. Exemplo com jQuery:
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
crossorigin="anonymous"></script>
Para folhas de estilo CSS do Bootstrap:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
crossorigin="anonymous">
Fontes web também podem ser verificadas:
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap"
rel="stylesheet"
integrity="sha384-..."
crossorigin="anonymous">
5. Geração automatizada de hashes em pipelines de build
Em projetos modernos, a geração manual de hashes é impraticável. Plugins como webpack-subresource-integrity automatizam o processo:
// webpack.config.js
const SriPlugin = require('webpack-subresource-integrity');
module.exports = {
output: {
crossOriginLoading: 'anonymous',
},
plugins: [
new SriPlugin({
hashFuncNames: ['sha384'],
enabled: process.env.NODE_ENV === 'production',
}),
],
};
Para pipelines CI/CD, scripts podem gerar hashes após o build:
# script-ci.sh
for file in dist/assets/*.js; do
hash=$(openssl dgst -sha384 -binary "$file" | openssl base64 -A)
echo "sha384-$hash"
done
Em templates HTML dinâmicos (Jinja2, EJS), os hashes podem ser injetados via variáveis:
<script src="{{ asset_url }}"
integrity="{{ asset_integrity }}"
crossorigin="anonymous"></script>
6. Limitações, riscos e boas práticas
O SRI não protege contra:
- Scripts inline (sem arquivo externo para verificar)
- Código first-party comprometido no servidor de origem
- Ataques de rede local (man-in-the-middle) se a conexão não for HTTPS
Problemas com versionamento: ao atualizar uma biblioteca, o hash quebra. É necessário atualizar simultaneamente o arquivo e o hash no HTML. Isso pode causar downtime se não for coordenado corretamente.
Boas práticas incluem combinar SRI com Content Security Policy (CSP):
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com;
O CSP fornece uma camada adicional, restringindo quais origens podem carregar scripts, enquanto o SRI garante a integridade do conteúdo carregado.
7. Monitoramento e troubleshooting de falhas SRI
Erros de SRI aparecem no console do navegador como:
Failed to find a valid digest in the 'integrity' attribute for resource 'https://...'
Para depuração, verifique:
- Se o hash foi gerado corretamente (mesmo algoritmo, conteúdo idêntico)
- Se o atributo crossorigin está presente e configurado como anonymous
- Se o servidor responde com cabeçalhos CORS adequados
Estratégias de fallback seguro:
<script>
// Fallback simples: recarregar sem SRI em caso de falha
var script = document.createElement('script');
script.src = 'https://cdn.example.com/library.js';
script.onerror = function() {
var fallback = document.createElement('script');
fallback.src = '/local/library.js';
document.head.appendChild(fallback);
};
document.head.appendChild(script);
</script>
Em produção, monitore erros de SRI via ferramentas como Sentry ou logs do console enviados para análise centralizada.
8. Conclusão e próximos passos
Checklist para adoção de SRI em projetos existentes:
- Identifique todos os recursos carregados de CDNs externas
- Gere hashes SHA-384 ou SHA-512 para cada recurso
- Adicione atributos
integrityecrossorigin="anonymous" - Configure CSP para complementar a proteção
- Automatize a geração de hashes no pipeline de build
- Implemente fallbacks seguros para recursos críticos
- Monitore erros de integridade em produção
Ferramentas complementares:
- sri-toolbox (npm) — biblioteca Node.js para validação e geração de hashes
- srihash.org — gerador online confiável (código aberto)
- Extensão "SRI Checker" para Chrome — verifica SRI em páginas visitadas
Tendências futuras incluem SRI para módulos ES6 (com type="module") e WebAssembly, expandindo a proteção para novas formas de distribuição de código.
Referências
- MDN Web Docs: Subresource Integrity — Documentação oficial completa sobre SRI, incluindo exemplos e especificações técnicas
- W3C Subresource Integrity Specification — Especificação formal do W3C que define o padrão SRI
- webpack-subresource-integrity plugin — Plugin oficial para integração de SRI com webpack
- SRI Hash Generator (srihash.org) — Ferramenta online open-source para gerar hashes SRI de arquivos
- Content Security Policy Reference — Guia prático sobre CSP, incluindo como combiná-lo com SRI para defesa em camadas