Subresource Integrity (SRI): Porque Carregar Scripts Externos Sem Hash é Dar Acesso Total ao Teu Checkout
O Ponto Cego da Cadeia de Fornecimento: Entregar as Chaves a um URL Externo
Abre o código-fonte de qualquer loja online, painel de administração ou página de vendas, e vais encontrar quase de certeza uma linha como esta:
<!-- O PERIGO ESCONDIDO: Script externo carregado sem validação criptográfica -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
Para muitos programadores, isto é apenas um atalho prático para não terem de compilar a biblioteca no projeto. Mas do ponto de vista de segurança, esta linha dá a um terceiro poder absoluto sobre a tua aplicação web.
COMO FUNCIONA UM ATAQUE À CADEIA DE FORNECIMENTO
- O Teu Cliente Entra no Checkout: Preenche o Cartão de Crédito e Morada
- O Browser Descarrega: https://cdn.jsdelivr.net/npm/chart.js
- ATAQUE NA CDN: Servidor Externo Invadido OU Conta de NPM Sequestrada!
- O Script Malicioso Corre com as Permissões do TEU Domínio: Lê o que o utilizador escreve nos campos de pagamento
- Rouba o número do cartão, data de validade e código CVV
- Envia os dados roubados para https://recolha-maliciosa-externa.com/
O JavaScript que corre no browser partilha o contexto de segurança da tua página através da política Same-Origin Policy. O browser não sabe distinguir se o código foi escrito por ti ou se veio de um servidor na outra ponta do mundo.
Um script externo corrompido pode:
- Intercetar os toques no teclado na página de pagamento (o conhecido ataque Magecart).
- Ler tokens de autenticação guardados no armazenamento local do navegador.
- Alterar os elementos da página para apresentar formulários falsos de login.
- Fazer pedidos à tua API em nome do utilizador autenticado sem que ele se aperceba.
Segundo a OWASP, os ataques à cadeia de fornecimento através de scripts externos não protegidos são uma das causas principais de fugas de informação em larga escala na web.
Nos nossos serviços de desenvolvimento de websites de alta performance e aplicações web, aplicamos regras estritas de isolamento para que nenhum script de terceiros coloque o teu negócio em perigo.
O Mecanismo do Subresource Integrity (SRI): A Barreira Criptográfica
O Subresource Integrity (SRI) é uma norma nativa da web desenhada especificamente para fechar esta vulnerabilidade. Em vez de confiares cegamente nos bytes que a CDN externa decide entregar hoje, o teu documento HTML declara o valor matemático exato do ficheiro que a tua equipa aprovou.
VALIDAÇÃO DE INTEGRIDADE CRIPTOGRÁFICA (SRI)
- O Teu Ficheiro HTML Contém:
- O Browser Descarrega o Ficheiro por HTTPS
- O Browser Calcula o Hash dos Bytes Recebidos: Hash Calculado: sha384-H83Bq… (Bate certo com o HTML!) → EXECUTA COM SEGURANÇA!
- SE O FICHEIRO FOI ADULTERADO OU INFETADO
- Hash Calculado: sha384-MALICIOSO… (NÃO COINCIDE!)
- Resultado: O BROWSER BLOQUEIA A EXECUÇÃO IMEDIATAMENTE!
- Aviso na Consola: “Failed to find a valid digest in the ‘integrity’ attribute…”
Se um invasor entrar nos servidores da CDN e adicionar dez linhas de código espião ao ficheiro, o hash SHA-384 muda radicalmente. O navegador rejeita o ficheiro de imediato e não o executa, protegendo os dados confidenciais dos teus clientes.
Passo a Passo: Como Gerar e Aplicar Hashes de SRI
Vamos ver como podes calcular e configurar estas proteções nos teus sites.
1. Como Gerar o Hash no Terminal Linux
Podes calcular o código de verificação diretamente na consola com as ferramentas padrão de OpenSSL:
# Descarrega o ficheiro e calcula o hash SHA-384 codificado em Base64
curl -s https://cdnjs.cloudflare.com/ajax/libs/alpinejs/3.13.5/cdn.min.js | \
openssl dgst -sha384 -binary | openssl base64 -A
O comando devolve-te uma cadeia criptográfica deste género:
k6O7yB+oXqC+9lZpD73sFmH8E0R4W2k1v5U3yXzB2o7uQ6v8w1A2b3c4d5e6f7g
2. Como Escrever a Tag Segura no Teu HTML
Coloca o resultado dentro do atributo integrity acompanhado da instrução crossorigin:
<script
src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/3.13.5/cdn.min.js"
integrity="sha384-k6O7yB+oXqC+9lZpD73sFmH8E0R4W2k1v5U3yXzB2o7uQ6v8w1A2b3c4d5e6f7g"
crossorigin="anonymous">
</script>
Porque Tens de Colocar crossorigin=“anonymous”
Se te esqueceres do atributo crossorigin="anonymous", o navegador ignora a verificação e o site pode dar erro! O browser precisa deste parâmetro para solicitar o ficheiro segundo as regras de CORS. Caso contrário, as regras de segurança entre domínios impedem o motor de JavaScript de ler os dados puros para calcular o hash. As grandes redes de distribuição como a Cloudflare já enviam estes cabeçalhos por omissão.
Como Automatizar a Criação de Hashes no Teu Processo de Build
Calcular hashes manualmente na consola serve para uma página estática simples, mas num projeto moderno com dezenas de ficheiros precisas de automatizar o processo.
Eis um script em Node.js que percorre os ficheiros HTML compilados, calcula os hashes dos scripts externos e insere as etiquetas de segurança automaticamente antes do deploy:
// scripts/injetar-sri.mjs - Script Automático de Injeção de SRI
import fs from 'node:fs';
import crypto from 'node:crypto';
import path from 'node:path';
async function obterHashSRI(url) {
const resposta = await fetch(url);
if (!resposta.ok) {
throw new Error(`Falha ao descarregar ${url}: ${resposta.statusText}`);
}
const buffer = await resposta.arrayBuffer();
const hash = crypto.createHash('sha384').update(Buffer.from(buffer)).digest('base64');
return `sha384-${hash}`;
}
async function protegerFicheiros(pastaBuild) {
const ficheiros = fs.readdirSync(pastaBuild).filter(f => f.endsWith('.html'));
for (const ficheiro of ficheiros) {
const caminhoCompleto = path.join(pastaBuild, ficheiro);
let html = fs.readFileSync(caminhoCompleto, 'utf-8');
// Expressão regular para encontrar scripts externos sem integridade
const regexScript = /<script\s+src="(https:\/\/[^"]+)"(?![^>]*integrity)[^>]*><\/script>/g;
let coincidencia;
while ((coincidencia = regexScript.exec(html)) !== null) {
const tagOriginal = coincidencia[0];
const urlScript = coincidencia[1];
console.log(`A calcular hash de SRI para: ${urlScript}`);
const hash = await obterHashSRI(urlScript);
const tagProtegida = `<script src="${urlScript}" integrity="${hash}" crossorigin="anonymous"></script>`;
html = html.replace(tagOriginal, tagProtegida);
}
fs.writeFileSync(caminhoCompleto, html, 'utf-8');
console.log(`Ficheiro protegido com SRI: ${ficheiro}`);
}
}
protegerFicheiros('./dist');
Colocando este script na tua pipeline de integração contínua no GitHub, os teus lançamentos ficam blindados sem exigirem esforço manual da tua equipa.
A Melhor Solução: Guardar Ficheiros Localmente e Forçar CSP
Apesar de o SRI ser indispensável quando és obrigado a usar serviços externos, a melhor decisão de engenharia segue o nosso princípio de anti-over-engineering: guarda as bibliotecas diretamente no teu servidor.
CDN EXTERNA VS FICHEIROS ALOJADOS NO PRÓPRIO SERVIDOR
- COM CDN EXTERNA (Frágil, Risco de Falhas e Ataques): Browser → Lê o HTML → Pede à cdn.externa.com (Novo DNS + Novo Handshake)
- ALOJADO NO TEU SERVIDOR (Robusto, Seguro e Rápido): Browser → Lê o HTML → Lê /assets/vendor.js (Mesmo Domínio, HTTP/2)
- Zero risco de ataques externos • Reutiliza a ligação de rede já aberta
- Cache permanente e imutável • Imune a quebras de serviços de terceiros
Bloquear Scripts Não Conformes com Content Security Policy
Para assegurares que ninguém na tua empresa adiciona scripts de fora sem verificação, ativa um cabeçalho rigoroso de Content Security Policy no teu servidor Nginx:
# Cabeçalho CSP no Nginx: Bloqueia scripts externos que não tenham hash SRI
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com; require-sri-for script style;" always;
A instrução require-sri-for script style; obriga o navegador a recusar o carregamento de qualquer script externo que não tenha uma tag de integridade válida.
Ao juntares o alojamento local de dependências, hashes automáticos de SRI e políticas rígidas de CSP, eliminas os riscos de segurança no frontend e proteges a tua faturação e a confiança dos teus clientes.
No terreno, em conjunto com a experiência acumulada na Webxtek Studio, aplicamos exatamente estes padrões operacionais em setores exigentes como cibersegurança b2b e inteligência corporativa e cibersegurança. Quando alinhas a tua estrutura através de websites de alta performance e anti-over-engineering, transformas boas práticas técnicas numa vantagem competitiva real e mensurável para o teu negócio.
[+] [ INDEX_DIRECTORY ] 17 tópicos ▼
- O Ponto Cego da Cadeia de Fornecimento: Entregar as Chaves a um URL Externo
- O Mecanismo do Subresource Integrity (SRI): A Barreira Criptográfica
- Passo a Passo: Como Gerar e Aplicar Hashes de SRI
- 1. Como Gerar o Hash no Terminal Linux
- 2. Como Escrever a Tag Segura no Teu HTML
- Porque Tens de Colocar crossorigin=“anonymous”
- Como Automatizar a Criação de Hashes no Teu Processo de Build
- A Melhor Solução: Guardar Ficheiros Localmente e Forçar CSP
- Bloquear Scripts Não Conformes com Content Security Policy
- Autor
- Perguntas Frequentes
- O que é o Subresource Integrity (SRI) e como é que o browser o valida?
- Porque é tão perigoso carregar bibliotecas diretamente de CDNs públicas sem fixar a versão?
- Porque é obrigatório colocar o atributo crossorigin="anonymous" ao usar SRI?
- O SRI consegue proteger scripts dinâmicos de gestores de tags como o Google Tag Manager?
- Nós Relacionados
- Sequência do Caminho
Perguntas Frequentes
O que é o Subresource Integrity (SRI) e como é que o browser o valida?
O Subresource Integrity (SRI) é uma especificação de segurança web que permite ao navegador confirmar se os ficheiros descarregados de servidores externos (como scripts ou ficheiros CSS) foram adulterados. Ao colocares o atributo `integrity="sha384-..."` na tag ` [ RELATED_NODES ]
> INICIAR_PROJETO
Precisa de um website que transmita confiança, apareça na pesquisa e dê mais força à sua presença digital? Comece a conversa aqui.