O Cenário de Ameaças em 2026
Segundo o relatório Verizon Data Breach Investigations Report 2025, aplicações web continuam sendo o vetor de ataque número um em incidentes de segurança corporativa — responsáveis por 43% de todas as violações de dados. Para desenvolvedores frontend, três categorias concentram a maioria dos riscos: injeção de scripts maliciosos, ataques à cadeia de dependências e exposição de dados sensíveis via APIs mal configuradas.
O OWASP Top 10 mais recente mantém Broken Access Control no topo, seguido de Cryptographic Failures e Injection (que inclui XSS). Não são ameaças abstratas: em 2024, o backdoor no XZ Utils (CVE-2024-3094) mostrou como um único pacote comprometido pode afetar infraestrutura crítica global. Em 2025, múltiplos pacotes npm populares foram sequestrados via typosquatting, afetando projetos React e Vue em produção.
1. XSS: Ainda a Ameaça Mais Comum no Frontend
Cross-Site Scripting (XSS) permite que atacantes injetem JavaScript malicioso no seu site, executando código no contexto do navegador da vítima. Em aplicações React e Next.js, o risco mais crítico é o uso incorreto de dangerouslySetInnerHTML.
// ❌ NUNCA faça isso com conteúdo não sanitizado function PostContent({ html }: { html: string }) { return; } // ✅ Sanitize SEMPRE antes de renderizar HTML externo import DOMPurify from "isomorphic-dompurify"; function PostContent({ html }: { html: string }) { const clean = DOMPurify.sanitize(html, { ALLOWED_TAGS: ["p", "h2", "h3", "ul", "ol", "li", "strong", "em", "code", "pre", "blockquote", "a"], ALLOWED_ATTR: ["href", "class", "id", "target", "rel"], }); return; }
O isomorphic-dompurify funciona tanto no servidor (SSR/RSC) quanto no cliente, essencial para aplicações Next.js. Nunca confie em HTML vindo de APIs externas, CMS ou input de usuário sem sanitização.
2. Content Security Policy: Sua Segunda Linha de Defesa
A CSP é um header HTTP que instrui o navegador a bloquear recursos não autorizados — mesmo que um atacante consiga injetar um script, a CSP impede sua execução. É a defesa mais eficaz contra XSS.
// next.config.ts
const securityHeaders = [
{
key: "Content-Security-Policy",
value: [
"default-src 'self'",
"script-src 'self' 'nonce-{nonce}'", // apenas scripts com nonce
"style-src 'self' 'unsafe-inline'", // Tailwind exige inline styles
"img-src 'self' data: https://images.unsplash.com https://secure.gravatar.com",
"font-src 'self'",
"connect-src 'self' https://api.emailjs.com https://api.brevo.com",
"frame-ancestors 'none'", // bloqueia clickjacking
"base-uri 'self'",
"form-action 'self'",
].join("; "),
},
{
key: "X-Frame-Options",
value: "DENY",
},
{
key: "X-Content-Type-Options",
value: "nosniff",
},
{
key: "Referrer-Policy",
value: "strict-origin-when-cross-origin",
},
{
key: "Permissions-Policy",
value: "camera=(), microphone=(), geolocation=()",
},
];
export default {
async headers() {
return [
{
source: "/(.*)",
headers: securityHeaders,
},
];
},
};
3. Supply Chain Attacks: O Risco que Vem das Dependências
Em março de 2024, o backdoor no XZ Utils (CVE-2024-3094) foi inserido por um contribuidor mal-intencionado após dois anos de construção de confiança na comunidade. O ataque não explorou uma falha de código — explorou a confiança humana no processo de open source.
Para projetos JavaScript, os riscos são ainda maiores dado o ecossistema massivo do npm:
- Typosquatting: pacotes com nomes similares aos legítimos (
lodahs,reakt) publicados para capturar erros de digitação - Dependency confusion: pacotes públicos com o mesmo nome de pacotes internos privados
- Account takeover: mantenedores com credenciais comprometidas publicam versões maliciosas
# Auditoria de segurança — rode regularmente
pnpm audit
# Verificar licenças e origens dos pacotes
npx license-checker --summary
# Verificar se o lockfile foi adulterado
pnpm install --frozen-lockfile # falha se o lockfile mudou
# Monitorar dependências com Dependabot (GitHub)
# Adicione .github/dependabot.yml ao repositório
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
4. Variáveis de Ambiente: O Erro Mais Comum em Next.js
O prefixo NEXT_PUBLIC_ em variáveis de ambiente do Next.js as torna visíveis no bundle do cliente. Esse comportamento é intencional — mas muitos devs não percebem e expõem segredos acidentalmente.
# ❌ NUNCA use NEXT_PUBLIC_ para segredos
NEXT_PUBLIC_DATABASE_PASSWORD=minha-senha-secreta # vaza no bundle!
NEXT_PUBLIC_API_SECRET_KEY=sk-prod-xxxxx # qualquer um pode ver!
# ✅ Segredos ficam SEM o prefixo (apenas server-side)
DATABASE_URL=postgresql://...
API_SECRET_KEY=sk-prod-xxxxx
REVALIDATE_SECRET=meu-segredo
# ✅ Apenas dados públicos levam o prefixo
NEXT_PUBLIC_SITE_URL=https://meusite.com.br
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXX
Para verificar o que está exposto no seu bundle, abra o DevTools → Sources e busque por nomes de variáveis suspeitas. Qualquer variável NEXT_PUBLIC_ aparecerá lá.
5. Autenticação e Gestão de Sessão
Erros de autenticação (OWASP A07:2021) seguem sendo responsáveis por uma fatia enorme das violações. Os padrões mais perigosos em aplicações modernas:
// ❌ Armazenar tokens em localStorage — vulnerável a XSS
localStorage.setItem("auth_token", token);
// ✅ Cookies HttpOnly via servidor — JavaScript não consegue ler
// Em uma Route Handler do Next.js:
import { cookies } from "next/headers";
export async function POST(request: Request) {
const { token } = await authenticateUser(request);
const cookieStore = await cookies();
cookieStore.set("session", token, {
httpOnly: true, // JavaScript não pode acessar
secure: true, // apenas HTTPS
sameSite: "strict", // proteção contra CSRF
maxAge: 60 * 60 * 24 * 7, // 7 dias
path: "/",
});
return Response.json({ success: true });
}
6. Rate Limiting em API Routes
API Routes sem rate limiting são alvos diretos de força bruta e DDoS de camada de aplicação. Em Next.js na Vercel, a solução mais simples é o middleware:
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
const rateLimit = new Map();
export function middleware(request: NextRequest) {
if (!request.nextUrl.pathname.startsWith("/api")) {
return NextResponse.next();
}
const ip = request.headers.get("x-forwarded-for") ?? "unknown";
const now = Date.now();
const windowMs = 60 * 1000; // 1 minuto
const maxRequests = 20;
const record = rateLimit.get(ip);
if (!record || now > record.resetAt) {
rateLimit.set(ip, { count: 1, resetAt: now + windowMs });
return NextResponse.next();
}
if (record.count >= maxRequests) {
return NextResponse.json(
{ error: "Too many requests" },
{ status: 429 }
);
}
record.count++;
return NextResponse.next();
}
7. Dependency Audit no CI/CD
Segurança precisa ser automatizada. Adicionar auditoria ao pipeline garante que nenhuma dependência vulnerável chegue à produçã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@v3
with:
version: 10
- run: pnpm install --frozen-lockfile
- run: pnpm audit --audit-level=high
# Falha o build se houver vulnerabilidade alta ou crítica
Checklist de Segurança para Deploy
- Nenhuma variável secreta com prefixo
NEXT_PUBLIC_ .env.localno.gitignore- Todo HTML externo sanitizado com DOMPurify antes de renderizar
- Headers de segurança configurados no
next.config.ts pnpm auditsem vulnerabilidades altas ou críticas- Tokens de autenticação em cookies HttpOnly, nunca em localStorage
- Rate limiting ativo em todas as API Routes públicas
- Dependabot configurado para atualizações automáticas
Segurança não é uma feature que você adiciona no final. É uma propriedade que você constrói desde a primeira linha de código. Um único campo sem sanitização pode comprometer toda a aplicação.
Conclusão
As ameaças de 2026 não são mais complexas do que as de anos anteriores — são mais automatizadas e direcionadas. Atacantes usam scanners que testam milhares de sites por hora em busca de configurações incorretas e dependências vulneráveis. A boa notícia é que as defesas são acessíveis: DOMPurify, CSP, cookies HttpOnly e auditoria de dependências resolvem a grande maioria dos vetores de ataque para aplicações frontend modernas. Implemente camada por camada, meça com ferramentas como o Mozilla Observatory e o OWASP ZAP, e trate segurança como parte do processo de desenvolvimento, não como checklist de último minuto.
Gostou do conteúdo?
Se você precisar de ajuda aplicando essas técnicas no seu projeto, estou disponível para consultoria.
Autor
Paulo Reducino
Desenvolvedor Frontend com 5+ anos de experiência em React, Next.js e TypeScript. Especialista em performance, SEO e acessibilidade. Atualmente na Vizuh (Londres, UK).



