Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Helmet e CSP no Node.js

Atualizado em: 19 de agosto de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

Helmet e CSP no Node.js ajudam a reduzir riscos comuns em aplicações web por meio de cabeçalhos HTTP de segurança. O Helmet configura vários headers úteis no Express, enquanto a Content Security Policy define quais origens podem fornecer scripts, estilos, imagens, fontes, frames e outros recursos. A combinação melhora a defesa contra XSS, clickjacking e carregamentos não autorizados, mas não substitui validação, escaping ou correção de vulnerabilidades no código.

Neste guia, você aprenderá a configurar Helmet e CSP de forma gradual, usar nonces em scripts legítimos, monitorar violações e evitar políticas tão permissivas que perdem o efeito. Para revisar a plataforma, consulte o que é Node.js e o tutorial de API com Node.js.

O que o Helmet faz?

Helmet é um middleware para aplicações compatíveis com Express. Ele adiciona ou ajusta headers como Content-Security-Policy, Cross-Origin-Opener-Policy, Referrer-Policy, Strict-Transport-Security e X-Content-Type-Options. Cada header protege uma fronteira diferente. Por isso, a configuração deve considerar se a aplicação serve HTML, funciona apenas como API, usa recursos de terceiros ou precisa ser incorporada em frames.

Não trate o pacote como uma caixa mágica. Um header pode bloquear funcionalidades legítimas, enquanto uma diretiva ampla pode permitir exatamente o conteúdo que deveria ser restringido. Leia a documentação e teste a resposta final depois de proxies, CDN e balanceadores.

Instalação e configuração inicial

npm init -y
npm install express helmet
npm install --save-dev supertest

Crie uma configuração explícita, principalmente para CSP. Em desenvolvimento, ferramentas de hot reload podem exigir regras diferentes. Não leve permissões temporárias para produção.

import crypto from 'node:crypto';
import express from 'express';
import helmet from 'helmet';

const app = express();

app.use((req, res, next) => {
  res.locals.cspNonce = crypto.randomBytes(16).toString('base64');
  next();
});

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: [
        "'self'",
        (req, res) => `'nonce-${res.locals.cspNonce}'`
      ],
      styleSrc: ["'self'"],
      imgSrc: ["'self'", 'data:', 'https:'],
      fontSrc: ["'self'"],
      connectSrc: ["'self'", 'https://api.example.com'],
      objectSrc: ["'none'"],
      baseUri: ["'self'"],
      frameAncestors: ["'none'"],
      formAction: ["'self'"]
    }
  },
  referrerPolicy: { policy: 'strict-origin-when-cross-origin' }
}));

O nonce muda a cada resposta e deve ser incluído apenas nos elementos de script autorizados. Ele não pode ser previsível nem reutilizado como valor fixo de configuração.

Como usar o nonce no HTML

Ao renderizar uma página no servidor, insira o nonce no atributo correspondente. Não monte o HTML com dados do usuário sem escaping.

app.get('/', (req, res) => {
  const nonce = res.locals.cspNonce;

  res.type('html').send(`
    <!doctype html>
    <html lang="pt-BR">
      <body>
        <h1>Painel</h1>
        <script nonce="${nonce}" src="/app.js"></script>
      </body>
    </html>
  `);
});

Scripts sem o nonce correto serão bloqueados pela política. Evite adicionar 'unsafe-inline' apenas para resolver rapidamente um erro, pois isso reduz a proteção contra injeção de script.

Política para APIs

Uma API que nunca entrega HTML pode desativar a CSP do Helmet, já que navegadores aplicam a política a documentos. Ainda assim, outros headers continuam úteis. Uma configuração de API deve revisar CORS, HSTS, MIME sniffing e exposição de informações. Leia também CORS em APIs Node.js e HTTPS e TLS no Node.js.

Comece com Report-Only

Em uma aplicação existente, ativar uma política restritiva diretamente pode quebrar scripts, fontes e integrações. Use inicialmente Content-Security-Policy-Report-Only para observar o que seria bloqueado. Analise os relatórios, remova dependências desnecessárias e depois aplique a política real.

app.use(helmet.contentSecurityPolicy({
  reportOnly: true,
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'"],
    objectSrc: ["'none'"],
    reportUri: ['/csp-report']
  }
}));

O endpoint de relatório deve limitar tamanho, validar JSON e aplicar rate limiting. Navegadores e extensões podem gerar ruído; não considere cada evento uma invasão confirmada.

Diretivas importantes

  • default-src: fallback para tipos sem diretiva específica;
  • script-src: controla JavaScript e deve ser o foco principal;
  • style-src: controla CSS e estilos inline;
  • connect-src: limita fetch, WebSocket e EventSource;
  • img-src: controla imagens e esquemas permitidos;
  • frame-ancestors: define quem pode incorporar a página;
  • object-src: normalmente deve ser 'none';
  • base-uri: impede alteração maliciosa da base de URLs;
  • form-action: restringe destinos de formulários.

Evite listas enormes de domínios

Permitir muitos hosts aumenta a superfície de confiança. Um domínio de CDN comprometido ou um endpoint que aceite upload pode tornar a regra insuficiente. Prefira recursos locais, integridade de sub-recurso quando aplicável e nonces ou hashes para scripts estritamente controlados.

Validação e segurança complementar

CSP é uma camada adicional. Continue escapando HTML, usando templates seguros, validando URLs e evitando APIs perigosas como innerHTML com conteúdo não confiável. O artigo sobre proteção contra ataques web apresenta outras medidas importantes.

  • não coloque segredos em HTML ou JavaScript;
  • use cookies Secure, HttpOnly e SameSite;
  • valide uploads e Content-Type;
  • restrinja frames e formulários;
  • mantenha dependências atualizadas;
  • trate CSP como defesa em profundidade.

Testes automatizados

Teste os headers nas rotas que servem documentos e nas respostas de erro. Confirme que o nonce está presente na política e no HTML, muda entre requisições e não aparece em scripts não autorizados.

import test from 'node:test';
import assert from 'node:assert/strict';
import request from 'supertest';
import { app } from './app.js';

test('envia CSP restritiva', async () => {
  const response = await request(app).get('/');
  const csp = response.headers['content-security-policy'];

  assert.match(csp, /default-src 'self'/);
  assert.match(csp, /object-src 'none'/);
  assert.match(csp, /nonce-/);
});

test('gera nonce diferente', async () => {
  const first = await request(app).get('/');
  const second = await request(app).get('/');

  assert.notEqual(
    first.headers['content-security-policy'],
    second.headers['content-security-policy']
  );
});

Integre testes de navegador para confirmar que recursos permitidos carregam e recursos não autorizados são bloqueados. Testes unitários com Jest também podem validar funções de configuração.

Observabilidade

Registre relatórios CSP com requestId, diretiva violada, origem do documento e recurso bloqueado. Remova query strings e dados pessoais antes de armazenar. Métricas devem agregar por diretiva e ambiente, evitando transformar URLs completas em labels.

Erros comuns

  • Adicionar unsafe-inline: resolve o sintoma e enfraquece a proteção;
  • Usar nonce fixo: um valor previsível pode ser reutilizado por conteúdo injetado;
  • Confiar apenas no Helmet: o pacote não corrige XSS no código;
  • Ignorar proxies: a resposta final pode ter headers removidos ou duplicados;
  • Ativar tudo sem testes: recursos legítimos podem parar de funcionar;
  • Permitir hosts amplos: subdomínios comprometidos passam a ser confiáveis.

Checklist de produção

  • CSP foi testada em modo Report-Only;
  • script-src não usa unsafe-inline;
  • nonce é criptográfico e muda por resposta;
  • object-src está bloqueado;
  • frame-ancestors e form-action estão definidos;
  • origens externas foram justificadas;
  • relatórios possuem limites e sanitização;
  • headers foram verificados após CDN e proxy.

Referências oficiais

Conclusão

Helmet facilita a configuração de cabeçalhos de segurança, e a CSP cria uma lista executável das fontes autorizadas para o documento. A melhor estratégia é começar restritivo, introduzir permissões somente quando justificadas, usar nonces em scripts legítimos e observar violações antes do bloqueio definitivo.

Uma política sólida não substitui código seguro, mas limita o impacto de várias falhas. Com testes, relatórios, revisão de dependências e configuração coerente em todos os ambientes, Helmet e CSP tornam a aplicação Node.js mais resistente sem depender de regras genéricas e permissivas.

Os 10 Melhores Cursos de Programação de 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita