saltar al contenido

Partes de esta página aún no están traducidas y aparecen en portugués. El texto original es siempre la referencia.

dogfooding

A segurança desta própria página

Uma knowledge base sobre segurança precisa praticar o que publica. Este é o checklist que ela mesma segue, e que você pode cobrar de qualquer site estático.

Superfície mínima
O site é 100% estático: sem servidor de aplicação, sem banco de dados, sem API, sem formulários. Não existe backend para explorar. O que é servido são apenas arquivos HTML, CSS e JS gerados em build.
Zero coleta de dados
Sem analytics, sem telemetria, sem cookies, sem fingerprinting, sem scripts de terceiros. Nada sobre você sai do seu navegador porque nada é pedido. O único dado guardado é o seu progresso de estudo (tópicos marcados e notas de quiz), em localStorage, só neste navegador e apagável a qualquer momento em /trilhas.
Cadeia de suprimentos controlada
Dependências com versões exatas e lockfile versionado (o próprio SCA desta KB). Fontes e assets são self-hosted; nenhum recurso é buscado de CDN em runtime. Detalhes do que entrou neste ciclo logo abaixo.
Cabeçalhos HTTP restritivos
O arquivo public/_headers define Content-Security-Policy, frame-ancestors 'none', nosniff, Permissions-Policy e políticas de isolamento para os hosts que o suportam (Netlify, Cloudflare Pages).

Content-Security-Policy

A CSP aplicada em produção, exposta de forma transparente:

default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
object-src 'none';
base-uri 'none';
frame-ancestors 'none';
form-action 'none';
upgrade-insecure-requests

Animações sem dependência de runtime

O site não carrega nenhuma biblioteca de animação. Uma versão anterior incluía uma (motion), mas ela nunca chegou a ser usada pelos componentes e custava cerca de 43 KB de gzip em toda página, então foi removida. Hoje todo o movimento é CSS puro em globals.css:

  • Entrada de página e do hero: keyframes curtos (240 a 400ms) com fade e deslocamento discreto.
  • Reveal sob scroll: animation-timeline: view(), só onde o navegador suporta, e desligado com prefers-reduced-motion.
  • Transição entre páginas: a API nativa de view transitions entre documentos (@view-transition), sem JavaScript e com fallback silencioso.

Menos dependências significam menos superfície de supply chain e nenhum acréscimo ao allowlist da CSP.

Portões automatizados de build

Toda promoção para out/ passa por dois scripts zero-dep, plugados direto no ciclo de vida do npm script: qualquer regra que falhe derruba o build antes do artefato ser publicado. Os números abaixo são do último build limpo.

prebuild

node --import ./scripts/content-alias-loader.mjs scripts/validate-content.mjs. Importa o conteúdo direto pelo Node 24 com type-stripping e aplica seis checagens de integridade:

  • R1 ids compostos únicos: cada domain/slug aparece uma vez só, em todos os domínios.
  • R2 relations resolvem: cada source e target de relação aponta para um tópico existente.
  • R3 itens de pipeline resolvem: cada pipelineStages[].items[].slug casa com um tópico do mesmo domínio.
  • R4 refs do glossário resolvem: cada entrada aponta para um tópico, com cross-domain permitido.
  • R5 etapas existentes: a etapa de cada tópico é uma etapa da esteira do seu domínio (o mapa de aprendizado posiciona os tópicos por nível e pré-requisitos, sem coordenadas manuais).
  • R6 piso de conteúdo live: para cada tópico em domínio live, ≥ 4 seções e (code ≥ 1 OR bullets ≥ 3) e tagline não vazia e ≥ 3 ferramentas. Todos os domínios são live e passam por esta régua.

postbuild

next build && node scripts/check-budget.mjs. O segundo script caminha out/ inteiro e compara as métricas (first-load, RSC prefetch, total, todos os idiomas, CSS, JS bruto e gzip, e a página inicial) contra tetos duros. Os tetos só sobem quando o conteúdo sobe, e cada mudança fica registrada, com os números medidos, no cabeçalho do scripts/check-budget.mjs. O status atual aparece no log de cada build e do CI.

Trade-offs honestos

  • script-src com 'unsafe-inline': o export estático do Next injeta pequenos scripts inline de hidratação. O caminho de endurecimento é migrar para CSP por hash ou nonce no deploy, documentado como próximo passo, não escondido.
  • style-src com 'unsafe-inline': o mapa de aprendizado posiciona setas e cartões com atributos style calculados no navegador. Sem isso o mapa não renderiza. Risco aceito e delimitado.
  • Onze domínios, 106 tópicos: o catálogo cobre AppSec, OWASP, Engenharia, DevOps, CloudSec, SecOps, resposta a incidentes, segurança ofensiva, GRC, Agentes e Vibecoding, todos com status live e passando no validador. A superfície de conteúdo cresceu desde a primeira publicação desta página, e o R6 (piso de conteúdo live) é o que segura a régua.
  • _headers depende do host: aberto via file:// ou servido por um servidor genérico, os cabeçalhos não se aplicam. A proteção entra em vigor no deploy, em host que respeite o arquivo.