Por que segurança em APIs é crítica?
APIs são a espinha dorsal de aplicações modernas. Uma vulnerabilidade pode resultar em:
- Vazamento de dados sensíveis
- Acesso não autorizado
- Denial of Service (DoS)
- Perda de confiança dos usuários
- Consequências legais e financeiras
1. Autenticação e Autorização
JWT (JSON Web Tokens)
JWT é o padrão moderno para autenticação stateless:
// Gerar token
const jwt = require('jsonwebtoken');
const token = jwt.sign(
{ userId: user.id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '24h' }
);
// Verificar token
const verifyToken = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'Token não fornecido' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
return res.status(401).json({ error: 'Token inválido' });
}
};
OAuth 2.0
Para aplicações mais complexas, use OAuth 2.0 com fluxos apropriados (Authorization Code, Client Credentials, etc.).
API Keys
Para acesso de aplicações, use API keys com rotação periódica:
// Middleware de validação de API Key
const validateApiKey = (req, res, next) => {
const apiKey = req.headers['x-api-key'];
if (!apiKey || !isValidApiKey(apiKey)) {
return res.status(401).json({ error: 'API Key inválida' });
}
req.apiKey = apiKey;
next();
};
2. HTTPS - Sempre Use
HTTPS é obrigatório. Nunca exponha APIs em HTTP:
- Criptografa dados em trânsito
- Previne man-in-the-middle attacks
- Protege credenciais
- Melhora SEO e confiança
3. Rate Limiting
Proteja sua API contra abuso e DoS:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutos
max: 100, // máximo 100 requests
message: 'Muitas requisições, tente novamente mais tarde',
standardHeaders: true,
legacyHeaders: false,
});
app.use('/api/', limiter);
// Rate limiting por IP e por usuário
const userLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 hora
max: 10, // 10 requisições por hora por usuário
keyGenerator: (req) => req.user?.id || req.ip,
});
4. Validação de Dados
Valide e sanitize todos os dados de entrada:
const { body, validationResult } = require('express-validator');
const validateUser = [
body('email').isEmail().normalizeEmail(),
body('password').isLength({ min: 8 }).matches(/[A-Z]/).matches(/[0-9]/),
body('name').trim().escape().isLength({ min: 2, max: 50 }),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
next();
}
];
5. Proteção contra SQL Injection
Use prepared statements ou ORMs:
// ❌ NUNCA faça isso
const query = `SELECT * FROM users WHERE email = '${email}'`;
// ✅ Use prepared statements
const query = 'SELECT * FROM users WHERE email = ?';
db.query(query, [email], (err, results) => {
// ...
});
// ✅ Ou use ORM
const user = await User.findOne({ where: { email } });
6. CORS (Cross-Origin Resource Sharing)
Configure CORS adequadamente:
const cors = require('cors');
const corsOptions = {
origin: process.env.ALLOWED_ORIGINS.split(','),
credentials: true,
optionsSuccessStatus: 200,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key'],
};
app.use(cors(corsOptions));
7. Headers de Segurança
Configure headers de segurança HTTP:
const helmet = require('helmet');
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));
8. Logging e Monitoramento
Registre atividades suspeitas:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }),
],
});
// Log de requisições suspeitas
app.use((req, res, next) => {
if (req.statusCode >= 400) {
logger.warn({
ip: req.ip,
method: req.method,
url: req.url,
statusCode: res.statusCode,
});
}
next();
});
9. Sanitização de Erros
Nunca exponha detalhes internos em erros:
// ❌ Ruim
res.status(500).json({ error: err.message });
// ✅ Bom
if (process.env.NODE_ENV === 'production') {
res.status(500).json({ error: 'Erro interno do servidor' });
} else {
res.status(500).json({ error: err.message });
}
10. Versionamento de API
Versione sua API para permitir mudanças sem quebrar clientes:
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
Checklist de Segurança
- ✅ HTTPS em produção
- ✅ Autenticação implementada
- ✅ Autorização por roles/permissões
- ✅ Rate limiting configurado
- ✅ Validação de entrada
- ✅ Proteção contra SQL injection
- ✅ CORS configurado corretamente
- ✅ Headers de segurança
- ✅ Logging de segurança
- ✅ Secrets em variáveis de ambiente
- ✅ Sanitização de erros
- ✅ Testes de segurança
Ferramentas de Teste
- OWASP ZAP: Scanner de vulnerabilidades
- Postman: Testes de API
- Burp Suite: Análise de segurança
- npm audit: Verificar dependências
Lembre-se: Segurança não é um produto, é um processo. Revise e atualize constantemente suas práticas de segurança.
Precisa de ajuda com segurança?
Nossa equipe pode ajudar você a implementar as melhores práticas de segurança em suas APIs.
Entre em Contato WhatsApp