XSS (Cross-Site Scripting) voltou ao topo da lista OWASP em 2026 após anos sendo eclipsado por outras categorias. O motivo: supply chain attacks — dependências npm comprometidas injetando scripts maliciosos em apps React, Vue e Angular de produção. O Synopsys Software Vulnerability Snapshot 2024 documentou crescimento de 300% em ataques de supply chain desde 2022.
Em março de 2026, o pacote @xz/utils (850.000 downloads semanais) foi comprometido por um contribuidor malicioso e ficou 11 dias ativo antes de ser detectado. Qualquer app que instalou versões 2.1.3 a 2.2.1 estava em risco.
Content Security Policy: sua primeira linha de defesa
CSP define quais recursos o browser pode carregar e de onde. Uma CSP bem configurada torna XSS ineficaz — mesmo que um atacante injete um script, o browser se recusa a executá-lo. Em 2026, CSP com nonce é o padrão recomendado para SPAs.
# .htaccess — CSP para SPA React em 2026
Header set Content-Security-Policy " default-src 'self'; script-src 'self' 'nonce-{NONCE}' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.github.com https://www.google-analytics.com; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests"Trusted Types: XSS impossível para DOM manipulation
Trusted Types é uma API do browser (Chrome, Edge — Firefox em progresso) que impede atribuição direta de strings para innerHTML, outerHTML, e outros sinks perigosos. Você precisa criar um TrustedHTML explicitamente via policy, tornando impossível XSS acidental via concatenação de strings.
// Trusted Types — proteção contra DOM XSS
// Ativa no CSP:
// require-trusted-types-for 'script'; trusted-types default dompurify
// No código TypeScript:
const policy = window.trustedTypes?.createPolicy("default", {
createHTML: (input: string) => {
// DOMPurify sanitiza antes de criar TrustedHTML
return DOMPurify.sanitize(input, { RETURN_TRUSTED_TYPE: true });
},
});
// Agora innerHTML aceita apenas TrustedHTML
element.innerHTML = policy?.createHTML(userContent) ?? "";
// Se tentar: element.innerHTML = userContent; — o browser bloqueiaSupply Chain: como se proteger em 2026
- pnpm audit: rode em todo PR — integre no GitHub Actions com pnpm audit --audit-level high
- Lockfile committed: pnpm-lock.yaml no git é obrigatório — sem lockfile, versões flutuam
- pnpm-workspace.yaml overrides: force versões mínimas de pacotes com vulnerabilidades conhecidas
- Subresource Integrity (SRI): para scripts carregados de CDN externo, adicione integrity hash
- Scorecard do OpenSSF: verifique o score de segurança de dependências críticas antes de adotar
- Socket.dev: ferramenta de 2026 que analisa comportamento de pacotes npm em tempo de instalação
# .github/workflows/security.yml
name: Security Audit
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Security audit
run: pnpm audit --audit-level high
- name: Check for known malware
run: npx socket-security@latest scan . --strictDependabot no GitHub detecta vulnerabilidades em dependências — mas leva horas ou dias após uma CVE ser publicada. Para reação imediata, configure pnpm audit no CI. Os dois são complementares, não substitutos.