Blog
Microfrontends arquivo

Subresource Integrity em microfrontends: blindagem 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.

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 usada em outros navegadores com 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 e se integram aos pipelines de CI/CD.

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

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

Exemplo com GitHub Actions

# .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. Use 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

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 o uso de SRI

Subresource Integrity é uma medida de segurança para arquiteturas de microfrontends: 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.

esc
  • Home Início
  • Sobre Trajetória e como trabalho
  • Blog Artigos sobre IA, plataforma e liderança
  • Projetos Demos públicos de frontend com IA
  • Currículo Web, PDF, Markdown e texto
  • Setup Hardware e ferramentas
  • Inference hooks do Claude: se o seu servidor de política cair, quem decide é um checkbox Arquitetura
  • Claude Code vazava o e-mail no User-Agent: o que eu checaria amanhã Segurança
  • Sete fases e onze testes: como a tela do agente aguenta queda, pausa e falta de rede Arquitetura
  • RAG no navegador custa 23 MB de download: como eu decidiria entre WebGPU e backend Arquitetura
↑↓ navegar ↵ abrir esc fechar