Voltar para o Blog

Segurança Web em 2025: OWASP Top 10 e Como Proteger Suas Aplicações JavaScript

Olá HaWkers, com ataques cibernéticos aumentando exponencialmente, segurança deixou de ser responsabilidade apenas de especialistas. Todo desenvolvedor precisa conhecer OWASP Top 10 e implementar proteções básicas.

Vamos explorar as vulnerabilidades mais comuns e como proteger suas aplicações JavaScript.

OWASP Top 10: As Vulnerabilidades Críticas

const owaspTop10_2025 = {
  1: 'Broken Access Control',
  2: 'Cryptographic Failures',
  3: 'Injection (SQL, XSS, etc)',
  4: 'Insecure Design',
  5: 'Security Misconfiguration',
  6: 'Vulnerable Components',
  7: 'Authentication Failures',
  8: 'Software and Data Integrity',
  9: 'Security Logging Failures',
  10: 'Server-Side Request Forgery (SSRF)'
};

1. Prevenindo XSS (Cross-Site Scripting)

// ❌ VULNERÁVEL - Nunca faça isso!
function renderUserInput(input) {
  document.getElementById('output').innerHTML = input;
  // Se input = "<script>alert('XSS')</script>"
  // Script executa!
}

// ✅ SEGURO - Sanitize input
import DOMPurify from 'dompurify';

function renderUserInputSafe(input) {
  const clean = DOMPurify.sanitize(input);
  document.getElementById('output').innerHTML = clean;
}

// ✅ AINDA MAIS SEGURO - Use textContent
function renderText(input) {
  document.getElementById('output').textContent = input;
  // HTML não é interpretado
}

// React automaticamente escapa
function UserProfile({ username }) {
  return <div>{username}</div>; // Safe!
}

2. SQL Injection Prevention

// ❌ VULNERÁVEL - String concatenation
async function getUser(userId) {
  const query = `SELECT * FROM users WHERE id = ${userId}`;
  // Se userId = "1 OR 1=1", retorna TODOS usuários!
  return await db.query(query);
}

// ✅ SEGURO - Prepared statements
async function getUserSafe(userId) {
  const query = 'SELECT * FROM users WHERE id = ?';
  return await db.query(query, [userId]);
}

// ✅ ORM ainda mais seguro
async function getUserORM(userId) {
  return await User.findById(userId);
  // ORM sanitiza automaticamente
}

3. Autenticação Segura

import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';

class AuthService {
  // Registrar usuário
  async register(email, password) {
    // Validar senha forte
    if (password.length < 12) {
      throw new Error('Senha deve ter mínimo 12 caracteres');
    }

    // Hash com bcrypt (NUNCA salve senha plain text!)
    const saltRounds = 12;
    const hashedPassword = await bcrypt.hash(password, saltRounds);

    await db.users.create({
      email,
      password: hashedPassword
    });
  }

  // Login
  async login(email, password) {
    const user = await db.users.findOne({ email });

    if (!user) {
      // ✅ Mensagem genérica (não revela se email existe)
      throw new Error('Credenciais inválidas');
    }

    // Verificar senha
    const isValid = await bcrypt.compare(password, user.password);

    if (!isValid) {
      throw new Error('Credenciais inválidas');
    }

    // JWT com expiração curta
    const token = jwt.sign(
      { userId: user.id, email: user.email },
      process.env.JWT_SECRET,
      { expiresIn: '1h' }
    );

    return { token, user: { id: user.id, email: user.email } };
  }

  // Verificar token
  verifyToken(token) {
    try {
      return jwt.verify(token, process.env.JWT_SECRET);
    } catch {
      throw new Error('Token inválido');
    }
  }
}

4. CSRF Protection

// Backend - Express
import csrf from 'csurf';

const csrfProtection = csrf({ cookie: true });

app.post('/api/transfer', csrfProtection, async (req, res) => {
  // Token CSRF validado automaticamente
  await processTransfer(req.body);
  res.json({ success: true });
});

// Frontend - Enviar token
async function transferMoney(amount, to) {
  const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

  await fetch('/api/transfer', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-Token': csrfToken
    },
    body: JSON.stringify({ amount, to })
  });
}

5. Validação de Input

import { z } from 'zod';

// Schema de validação
const userSchema = z.object({
  email: z.string().email(),
  age: z.number().min(18).max(120),
  username: z.string().min(3).max(20).regex(/^[a-zA-Z0-9_]+$/)
});

// Validar input
async function createUser(data) {
  try {
    // Valida e parse
    const validated = userSchema.parse(data);

    // ✅ Dados garantidamente válidos
    return await db.users.create(validated);
  } catch (error) {
    throw new Error('Dados inválidos');
  }
}

6. Rate Limiting

import rateLimit from 'express-rate-limit';

// Prevenir brute force
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutos
  max: 5, // 5 tentativas
  message: 'Muitas tentativas de login. Tente em 15 minutos.'
});

app.post('/api/login', loginLimiter, async (req, res) => {
  // Login logic
});

// Rate limit geral
const apiLimiter = rateLimit({
  windowMs: 60 * 1000, // 1 minuto
  max: 100 // 100 requests
});

app.use('/api/', apiLimiter);

7. Secure Headers

import helmet from 'helmet';

// Express - Helmet configura headers seguros
app.use(helmet());

// Headers importantes:
const securityHeaders = {
  'Content-Security-Policy': "default-src 'self'",
  'X-Frame-Options': 'DENY',
  'X-Content-Type-Options': 'nosniff',
  'Strict-Transport-Security': 'max-age=31536000',
  'X-XSS-Protection': '1; mode=block'
};

Checklist de Segurança

const securityChecklist = [
  '✅ Validar TODO input do usuário',
  '✅ Usar prepared statements (SQL)',
  '✅ Sanitizar output HTML',
  '✅ Implementar rate limiting',
  '✅ HTTPS em produção (sempre!)',
  '✅ Passwords hasheadas com bcrypt',
  '✅ JWT com expiração curta',
  '✅ CSRF tokens em forms',
  '✅ Security headers (Helmet)',
  '✅ Dependências atualizadas',
  '✅ Secrets em env vars',
  '✅ Logging de eventos de segurança',
  '✅ CORS configurado corretamente'
];

Segurança não é opcional em 2025. Com ataques cada vez mais sofisticados, todo desenvolvedor é responsável por código seguro.

Bora pra cima! 🦅

🎯 Desenvolvedores Seguros Têm Mais Valor

Conhecimento de segurança diferencia desenvolvedores júniors de profissionais completos. Invista em conhecimento sólido.

Comece agora:

  • R$9,90 (pagamento único)

🚀 Acessar Guia Completo

Comentários (0)

Esse artigo ainda não possui comentários 😢. Seja o primeiro! 🚀🦅

Adicionar comentário