Voltar ao Blog

Microfrontends

Subresource Integrity em Microfrontends: Blindagem Essencial para sua Arquitetura

Como implementar Subresource Integrity (SRI) em microfrontends para garantir segurança contra código malicioso, ataques a CDNs e modificações não autorizadas em módulos carregados dinamicamente.

5 de junho de 2025 6 min

Em arquiteturas modernas com Micro Frontends (MFE), especialmente aquelas que utilizam importmap ou System.import() com frameworks como single-spa, é comum carregar módulos JavaScript dinamicamente a partir de CDNs ou buckets públicos. No entanto, essa flexibilidade traz desafios significativos de segurança.

🚨 O Desafio

Carregamento Dinâmico

  • Módulos carregados em tempo de execução
  • Execução de código malicioso se arquivos forem comprometidos
  • Falta de verificação de integridade

Ambientes Distribuídos

  • Múltiplos times e pipelines de CI/CD
  • Garantir integridade dos módulos se torna complexo
  • Coordenação difícil entre equipes

CDNs e Buckets Públicos

  • Recursos hospedados em terceiros
  • Alvo de ataques ou modificações não autorizadas
  • Falta de controle sobre o conteúdo servido

✅ A Solução: Subresource Integrity (SRI) com Import Maps

A recente introdução do campo “integrity” nos importmaps permite especificar hashes criptográficos para cada módulo, garantindo que apenas o código esperado seja executado pelo navegador. Essa funcionalidade já é suportada nativamente no Chrome e pode ser utilizada em outros navegadores com o auxílio de polyfills como o ES Module Shims.

Exemplo de Import Map com SRI:

<script type="importmap">
{
  "imports": {
    "app": "https://cdn.example.com/[email protected]/index.js",
    "react": "https://cdn.example.com/[email protected]/index.js",
    "vue": "https://cdn.example.com/[email protected]/index.js"
  },
  "integrity": {
    "https://cdn.example.com/[email protected]/index.js": "sha384-abc123def456...",
    "https://cdn.example.com/[email protected]/index.js": "sha384-xyz789ghi012...",
    "https://cdn.example.com/[email protected]/index.js": "sha384-mno345pqr678..."
  }
}
</script>

🔐 Como Gerar o Hash de Integridade

Comando para Gerar SHA-384:

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

Exemplo Prático:

# Gerar hash para um arquivo específico
openssl dgst -sha384 -binary dist/app.js | openssl base64 -A

# Resultado: sha384-abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567...

Script Automatizado:

#!/bin/bash
# generate-sri.sh

generate_sri() {
    local file=$1
    local hash=$(openssl dgst -sha384 -binary "$file" | openssl base64 -A)
    echo "sha384-$hash"
}

# Gerar hashes para todos os arquivos JS
for file in dist/*.js; do
    echo "$(basename "$file"): $(generate_sri "$file")"
done

🛠️ Integração com CI/CD

JSPM Generator

Ferramentas como o JSPM Generator facilitam a geração automática de import maps com hashes de integridade, integrando-se perfeitamente aos pipelines de CI/CD.

# Instalar JSPM Generator
npm install -g @jspm/generator

# Gerar import map com SRI
jspm generate --integrity --map dist/

GitHub Actions Example:

# .github/workflows/build-and-deploy.yml
name: Build and Deploy with SRI

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Build application
        run: npm run build
        
      - name: Generate SRI hashes
        run: |
          # Gerar hashes para todos os arquivos JS
          for file in dist/*.js; do
            hash=$(openssl dgst -sha384 -binary "$file" | openssl base64 -A)
            echo "sha384-$hash" > "${file}.sri"
          done
          
      - name: Update import map
        run: |
          # Atualizar import map com hashes gerados
          node scripts/update-importmap.js
          
      - name: Deploy to CDN
        run: |
          # Deploy para CDN com arquivos e import map
          aws s3 sync dist/ s3://your-cdn-bucket/

⚠️ Casos Reais de Comprometimento

Ataques a CDNs

  • 🚨 Polyfill.io: O recente ataque demonstrou como a falta de verificação de integridade pode levar à injeção de código malicioso em larga escala
  • 🚨 Bootstrap CDN: Histórico de ataques similares em CDNs populares
  • 🚨 jQuery CDN: Vulnerabilidades exploradas através de modificações não autorizadas

Modificações Não Autorizadas

  • 🚨 Versões antigas de módulos sobrescritas inadvertidamente
  • 🚨 Vulnerabilidades introduzidas por mudanças não controladas
  • 🚨 Código malicioso injetado em ambientes de produção

🛡️ Boas Práticas

1. Utilize SRI em Todos os Módulos

<!-- ✅ Bom: SRI em todos os módulos -->
<script type="importmap">
{
  "imports": {
    "app": "https://cdn.example.com/[email protected]/index.js",
    "vendor": "https://cdn.example.com/[email protected]/index.js"
  },
  "integrity": {
    "https://cdn.example.com/[email protected]/index.js": "sha384-abc123...",
    "https://cdn.example.com/[email protected]/index.js": "sha384-xyz789..."
  }
}
</script>

2. Combine com Políticas de Segurança

<!-- Content Security Policy com SRI obrigatório -->
<meta http-equiv="Content-Security-Policy" 
      content="require-sri-for script; script-src 'self' https://cdn.example.com;">

3. Automatize no Pipeline

// scripts/update-importmap.js
const fs = require('fs');
const crypto = require('crypto');

function generateSRI(filePath) {
  const content = fs.readFileSync(filePath);
  const hash = crypto.createHash('sha384').update(content).digest('base64');
  return `sha384-${hash}`;
}

function updateImportMap() {
  const importMap = {
    imports: {
      "app": "https://cdn.example.com/[email protected]/index.js"
    },
    integrity: {}
  };
  
  // Gerar hash para cada arquivo
  const files = ['dist/app.js', 'dist/vendor.js'];
  files.forEach(file => {
    const url = `https://cdn.example.com/${file}`;
    importMap.integrity[url] = generateSRI(file);
  });
  
  // Salvar import map atualizado
  fs.writeFileSync('dist/importmap.json', JSON.stringify(importMap, null, 2));
}

updateImportMap();

🔧 Implementação Prática

Single-SPA com SRI

// main.js
import { registerApplication, start } from 'single-spa';

// Import map com SRI
const importMap = {
  imports: {
    "react": "https://cdn.example.com/[email protected]/index.js",
    "vue": "https://cdn.example.com/[email protected]/index.js"
  },
  integrity: {
    "https://cdn.example.com/[email protected]/index.js": "sha384-abc123...",
    "https://cdn.example.com/[email protected]/index.js": "sha384-xyz789..."
  }
};

// Registrar aplicações com SRI
registerApplication({
  name: 'react-app',
  app: () => System.import('react'),
  activeWhen: '/react'
});

registerApplication({
  name: 'vue-app', 
  app: () => System.import('vue'),
  activeWhen: '/vue'
});

start();

Fallback para Navegadores Antigos

<!-- ES Module Shims para suporte a SRI em navegadores antigos -->
<script async src="https://ga.jspm.io/npm:[email protected]/dist/es-module-shims.js"></script>

<script type="importmap">
{
  "imports": {
    "app": "https://cdn.example.com/[email protected]/index.js"
  },
  "integrity": {
    "https://cdn.example.com/[email protected]/index.js": "sha384-abc123..."
  }
}
</script>

📊 Monitoramento e Alertas

Verificação de Integridade

// Verificar integridade em tempo de execução
function verifyIntegrity(url, expectedHash) {
  return fetch(url)
    .then(response => response.arrayBuffer())
    .then(buffer => {
      const hash = crypto.subtle.digest('SHA-384', buffer);
      return hash.then(hashBuffer => {
        const hashArray = new Uint8Array(hashBuffer);
        const hashBase64 = btoa(String.fromCharCode(...hashArray));
        return `sha384-${hashBase64}` === expectedHash;
      });
    });
}

// Uso
verifyIntegrity(
  'https://cdn.example.com/[email protected]/index.js',
  'sha384-abc123...'
).then(isValid => {
  if (!isValid) {
    console.error('❌ Integridade comprometida!');
    // Implementar alertas ou fallbacks
  }
});

🚀 Benefícios da Implementação

Segurança

  • Proteção contra código malicioso injetado
  • Verificação de integridade automática
  • Prevenção de ataques a CDNs

Confiabilidade

  • Garantia de código válido em produção
  • Prevenção de modificações não autorizadas
  • Auditoria de integridade completa

Compliance

  • Atendimento a padrões de segurança
  • Documentação de integridade para auditorias
  • Rastreabilidade de mudanças

📋 Checklist de Implementação

  • Gerar hashes SRI para todos os módulos
  • Atualizar import maps com campos de integridade
  • Implementar CSP com require-sri-for
  • Automatizar geração no pipeline CI/CD
  • Configurar monitoramento de integridade
  • Implementar fallbacks para navegadores antigos
  • Documentar processo de atualização de hashes
  • Treinar equipe sobre boas práticas de SRI

Este artigo apresenta uma medida essencial de segurança para arquiteturas de microfrontends. A implementação de Subresource Integrity protege contra ataques e garante que apenas código validado seja executado. Para discussões técnicas, implementações ou dúvidas sobre segurança em microfrontends, me encontre no LinkedIn ou GitHub.

Logo eliseu.dev

Software Developer especializado em Arquitetura de Software e Engenharia de Plataformas.

Currículo

Navegação

© 2026 Eliseu Santos. Todos os direitos reservados.

Feito com ❤️ e muito café