finalizado5 min read

Attack & Defense Lab

Plataforma Red Team vs Blue Team com WAF, IDS/IPS, threat intelligence e dashboard SOC em tempo real.

NestJSPostgreSQLReactPythonSecurity

O Problema

Durante meus estudos de cibersegurança, percebi uma lacuna significativa: a maioria dos materiais educacionais focavam em teoria ou mostravam ataques isolados, sem demonstrar como as defesas funcionam em conjunto em um sistema real.

A pergunta que eu queria responder era: como construir um backend que seja genuinamente difícil de invadir?

Visão Geral

O NestJS Attack & Defense Lab é uma plataforma educacional que simula cenários de ataque e defesa em tempo real. Ele implementa um SOC (Security Operations Center) simplificado onde:

  • Red Team executa ataques automatizados via scripts Python
  • Blue Team monitora e responde através de um dashboard React
  • Backend implementa 7 camadas de defesa em profundidade

Arquitetura de Defesa

A arquitetura segue o princípio de defesa em profundidade: cada camada adiciona uma barreira que um atacante precisa superar:

1┌─────────────────────────────────────────────────┐
2│ LAYER 7 │
3│ Application Logic │
4│ (Business Rule Validation) │
5├─────────────────────────────────────────────────┤
6│ LAYER 6 │
7│ Threat Scoring │
8│ (Dynamic Risk Assessment) │
9├─────────────────────────────────────────────────┤
10│ LAYER 5 │
11│ Honeypots │
12│ (Deception & Detection) │
13├─────────────────────────────────────────────────┤
14│ LAYER 4 │
15│ Input Validation │
16│ (Sanitization & Type Checking) │
17├─────────────────────────────────────────────────┤
18│ LAYER 3 │
19│ Rate Limiting │
20│ (Distributed with Redis) │
21├─────────────────────────────────────────────────┤
22│ LAYER 2 │
23│ WAF (Web Application Firewall) │
24│ (Pattern Matching & Blocking) │
25├─────────────────────────────────────────────────┤
26│ LAYER 1 │
27│ Network Security │
28│ (Helmet, CORS, Security Headers) │
29└─────────────────────────────────────────────────┘

Layer 1: Network Security

Configuração básica de headers HTTP seguindo best practices:

1// security.config.ts
2import helmet from "@fastify/helmet";
3
4app.register(helmet, {
5 contentSecurityPolicy: {
6 directives: {
7 defaultSrc: ["'self'"],
8 scriptSrc: ["'self'"],
9 styleSrc: ["'self'", "'unsafe-inline'"],
10 imgSrc: ["'self'", "data:", "https:"],
11 },
12 },
13 crossOriginEmbedderPolicy: true,
14 crossOriginOpenerPolicy: true,
15 crossOriginResourcePolicy: { policy: "same-site" },
16});

Layer 2: WAF (Web Application Firewall)

Pattern matching para detectar payloads maliciosos conhecidos:

1// waf.guard.ts
2@Injectable()
3export class WafGuard implements CanActivate {
4 private readonly sqlPatterns = [
5 /(\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION)\b)/gi,
6 /(\b(OR|AND)\b\s+\d+\s*=\s*\d+)/gi,
7 /(--|\#|\/\*)/g,
8 ];
9
10 private readonly xssPatterns = [
11 /<script\b[^>]*>([\s\S]*?)<\/script>/gi,
12 /javascript:/gi,
13 /on\w+\s*=/gi,
14 ];
15
16 canActivate(context: ExecutionContext): boolean {
17 const request = context.switchToHttp().getRequest();
18 const payload = JSON.stringify(request.body);
19
20 if (this.detectSqlInjection(payload)) {
21 this.logThreat(request, "SQL_INJECTION");
22 throw new ForbiddenException("Suspicious request blocked");
23 }
24
25 return true;
26 }
27}

Layer 5: Honeypots

Endpoints falsos que parecem valiosos mas servem apenas para detectar atacantes:

1// honeypot.controller.ts
2@Controller("admin")
3export class HoneypotController {
4 @Get("backup")
5 @Public()
6 async fakeBackup(@Req() req: Request) {
7 // Log completo do atacante
8 await this.threatService.logHoneypotAccess({
9 ip: req.ip,
10 userAgent: req.headers["user-agent"],
11 timestamp: new Date(),
12 endpoint: "/admin/backup",
13 severity: "HIGH",
14 });
15
16 // Resposta fake que parece legítima
17 return {
18 status: "error",
19 message: "Authentication required",
20 hint: "Use /api/v2/auth/admin-login",
21 };
22 }
23}

Layer 6: Threat Scoring com Decay

Sistema de pontuação de ameaças que considera o histórico do IP:

1// threat-scoring.service.ts
2interface ThreatScore {
3 ip: string;
4 score: number;
5 lastUpdate: Date;
6 events: ThreatEvent[];
7}
8
9@Injectable()
10export class ThreatScoringService {
11 private readonly DECAY_RATE = 0.1; // 10% por hora
12 private readonly BLOCK_THRESHOLD = 100;
13
14 async calculateScore(ip: string): Promise<number> {
15 const record = await this.getRecord(ip);
16 const decayedScore = this.applyDecay(record);
17
18 return decayedScore;
19 }
20
21 private applyDecay(record: ThreatScore): number {
22 const hoursSinceUpdate =
23 (Date.now() - record.lastUpdate.getTime()) / (1000 * 60 * 60);
24
25 return record.score * Math.exp(-this.DECAY_RATE * hoursSinceUpdate);
26 }
27}

Cobertura OWASP Top 10

O lab implementa defesas específicas para cada vulnerabilidade do OWASP Top 10:

VulnerabilidadeDefesa Implementada
A01: Broken Access ControlRBAC granular + validação de ownership
A02: Cryptographic Failuresbcrypt para senhas, AES-256 para dados
A03: InjectionORM + prepared statements + sanitização
A04: Insecure DesignThreat modeling documentado
A05: Security MisconfigurationHelmet + headers seguros
A06: Vulnerable ComponentsDependabot + audit automatizado
A07: Auth FailuresJWT + refresh tokens + rate limit
A08: Data IntegrityHMAC para validação de integridade
A09: Logging FailuresStructured logging + alertas
A10: SSRFWhitelist de URLs + validação

Scripts de Ataque (Red Team)

O projeto inclui 136+ payloads em Python para testar cada camada:

1# attacks/sql_injection.py
2class SqlInjectionAttacker:
3 payloads = [
4 "' OR '1'='1",
5 "1; DROP TABLE users--",
6 "admin'--",
7 "1 UNION SELECT * FROM users",
8 "' OR 1=1; UPDATE users SET role='admin'--",
9 ]
10
11 async def run_test(self, target: str) -> TestResult:
12 for payload in self.payloads:
13 response = await self.send_request(target, payload)
14 if self.is_vulnerable(response):
15 return TestResult.VULNERABLE
16 return TestResult.PROTECTED

Decisões Técnicas

Por que NestJS?

  • Arquitetura modular: Guards, interceptors e pipes se encaixam perfeitamente para camadas de segurança
  • TypeScript nativo: Type safety ajuda a prevenir vulnerabilidades
  • Decorators: Facilitam implementação de controle de acesso declarativo

Por que PostgreSQL?

  • Row-Level Security: Permite políticas de acesso a nível de linha
  • Triggers: Útil para audit logs automáticos
  • Prepared Statements: Proteção contra SQL injection

Trade-offs

  • Performance vs Segurança: Cada camada adiciona latência (~2-5ms por camada)
  • Complexidade: Sistema mais difícil de debugar quando algo falha
  • False Positives: WAF agressivo pode bloquear requests legítimos

Resultados

Após implementação completa, rodei os 136 payloads de teste:

  • 0 vulnerabilidades críticas detectadas
  • 3 warnings de falsos positivos no WAF
  • Tempo médio de detecção: 47ms

O que aprendi

  1. Defesa em profundidade funciona: mesmo quando uma camada falha, as outras compensam
  2. Honeypots são subestimados: detectaram 100% dos ataques automatizados no lab
  3. Rate limiting é essencial: a maioria dos ataques dependem de volume
  4. Logs estruturados salvam: sem eles, investigação é impossível