---
title: "Subresource Integrity em Microfrontends: Blindagem Essencial para sua Arquitetura"
slug: subresource-integrity-microfrontends
date: 2025-06-05
category: "Microfrontends"
tags: ["subresource-integrity", "sri", "microfrontends", "security", "import-maps", "cdn-security", "javascript-security"]
readTime: "6 min"
excerpt: "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."
url: https://eliseu.dev/blog/subresource-integrity-microfrontends
---

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:**

```html
<script type="importmap">
{
  "imports": {
    "app": "https://cdn.example.com/app@1.0.0/index.js",
    "react": "https://cdn.example.com/react@18.2.0/index.js",
    "vue": "https://cdn.example.com/vue@3.4.0/index.js"
  },
  "integrity": {
    "https://cdn.example.com/app@1.0.0/index.js": "sha384-abc123def456...",
    "https://cdn.example.com/react@18.2.0/index.js": "sha384-xyz789ghi012...",
    "https://cdn.example.com/vue@3.4.0/index.js": "sha384-mno345pqr678..."
  }
}
</script>
```

## 🔐 Como Gerar o Hash de Integridade

### **Comando para Gerar SHA-384:**

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

### **Exemplo Prático:**

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

# Resultado: sha384-abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567...
```

### **Script Automatizado:**

```bash
#!/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.

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

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

### **GitHub Actions Example:**

```yaml
# .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**
```html
<!-- ✅ Bom: SRI em todos os módulos -->
<script type="importmap">
{
  "imports": {
    "app": "https://cdn.example.com/app@1.0.0/index.js",
    "vendor": "https://cdn.example.com/vendor@2.0.0/index.js"
  },
  "integrity": {
    "https://cdn.example.com/app@1.0.0/index.js": "sha384-abc123...",
    "https://cdn.example.com/vendor@2.0.0/index.js": "sha384-xyz789..."
  }
}
</script>
```

### **2. Combine com Políticas de Segurança**
```html
<!-- 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**
```javascript
// 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/app@1.0.0/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**

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

// Import map com SRI
const importMap = {
  imports: {
    "react": "https://cdn.example.com/react@18.2.0/index.js",
    "vue": "https://cdn.example.com/vue@3.4.0/index.js"
  },
  integrity: {
    "https://cdn.example.com/react@18.2.0/index.js": "sha384-abc123...",
    "https://cdn.example.com/vue@3.4.0/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**

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

<script type="importmap">
{
  "imports": {
    "app": "https://cdn.example.com/app@1.0.0/index.js"
  },
  "integrity": {
    "https://cdn.example.com/app@1.0.0/index.js": "sha384-abc123..."
  }
}
</script>
```

## 📊 Monitoramento e Alertas

### **Verificação de Integridade**

```javascript
// 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/app@1.0.0/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](https://linkedin.com/in/eliseusantos) ou [GitHub](https://github.com/EliseuSantos).*