- Added a detailed deployment guide (DEPLOYMENT_GUIDE.md) for frontend and backend setup. - Created an index documentation (INDEX.md) summarizing changes and available resources. - Established Nginx security configuration (NGINX_SECURITY_CONFIG.md) to protect backend IP and enforce rate limiting. - Developed a backend security guide (SECURITY_BACKEND_GUIDE.md) outlining security measures and best practices. - Introduced middleware for security, including rate limiting, CORS, and Cloudflare validation. - Updated frontend components and services to improve security and user experience. - Implemented logging and monitoring strategies for better security oversight.
11 KiB
11 KiB
Guía de Seguridad Backend para Amayo
Esta guía contiene las mejoras de seguridad implementadas en el frontend y las recomendaciones para el backend para proteger la IP del servidor.
🛡️ Problema Identificado
Según el video de referencia (https://youtu.be/iXOlQszplC8), incluso con Cloudflare, un atacante puede:
- Ver el código fuente del frontend y encontrar URLs del backend
- Realizar timing attacks para encontrar la IP real del servidor
- Bypassear Cloudflare usando técnicas de header manipulation
✅ Soluciones Implementadas en el Frontend
1. Servicio de Seguridad (src/services/security.js)
Características:
- No expone URLs directamente en el código: Las URLs se obtienen dinámicamente
- Token de sesión único: Genera un token por sesión para identificar clientes
- Headers de seguridad: Incluye timestamps y tokens en cada request
- Rate limiting client-side: Previene abuso desde el cliente
- Validación de respuestas: Verifica la autenticidad de las respuestas del servidor
2. Sistema de Rate Limiting
Implementado en security.js:
- Login: 3 intentos por minuto
- API calls: 30 requests por minuto
- Default: 10 requests por minuto
3. Protección CSRF
- State parameter en OAuth2
- Validación de state en callbacks
- Tokens de sesión únicos
4. Caché de Datos
- Stats del bot: 5 minutos
- Info del bot: 1 hora
- Reduce requests innecesarios
🔧 Recomendaciones para el Backend
1. Configuración de Cloudflare
A. Activar IP Anonymization
Cloudflare Dashboard > Security > Settings > Privacy > Enable IP Geolocation
B. Bot Fight Mode
Cloudflare Dashboard > Security > Bots > Enable Bot Fight Mode
C. Under Attack Mode (opcional)
Para protección extra cuando se detecte un ataque:
Cloudflare Dashboard > Security > Settings > Security Level > I'm Under Attack
D. Reglas de Firewall Personalizadas
# Bloquear acceso directo a la IP
- Si el request no viene de Cloudflare (validar CF-Connecting-IP)
- Bloquear requests sin User-Agent
- Bloquear requests sin X-Requested-With
# Rate Limiting Avanzado
- 30 requests/minuto por IP
- 100 requests/minuto por usuario autenticado
2. Configuración del Servidor Backend (Express.js ejemplo)
// middleware/security.js
import rateLimit from 'express-rate-limit';
import helmet from 'helmet';
// Verificar que el request viene de Cloudflare
export const cloudflareOnly = (req, res, next) => {
const cfIp = req.headers['cf-connecting-ip'];
// Lista de IPs de Cloudflare (actualizar periódicamente)
const cloudflareIPs = [
// https://www.cloudflare.com/ips/
'173.245.48.0/20',
'103.21.244.0/22',
// ... más IPs
];
if (!cfIp || !isCloudflareIP(req.ip, cloudflareIPs)) {
return res.status(403).json({ error: 'Direct access forbidden' });
}
next();
};
// Rate limiting por endpoint
export const apiLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minuto
max: 30, // 30 requests
message: 'Too many requests from this IP',
standardHeaders: true,
legacyHeaders: false,
skip: (req) => {
// Skip para requests autenticados con rate limit más alto
return req.user && req.user.premium;
}
});
export const authLimiter = rateLimit({
windowMs: 60 * 1000,
max: 3, // Solo 3 intentos de login por minuto
skipSuccessfulRequests: true
});
// Headers de seguridad
export const securityHeaders = helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
},
referrerPolicy: { policy: 'same-origin' },
noSniff: true,
xssFilter: true,
frameguard: { action: 'deny' }
});
3. Validación de Headers
// middleware/validateRequest.js
export const validateSecurityHeaders = (req, res, next) => {
const requiredHeaders = [
'x-client-token',
'x-requested-with',
'x-timestamp'
];
// Verificar headers obligatorios
for (const header of requiredHeaders) {
if (!req.headers[header]) {
return res.status(400).json({
error: 'Missing security headers'
});
}
}
// Validar timestamp (prevenir replay attacks)
const timestamp = parseInt(req.headers['x-timestamp']);
const now = Date.now();
const maxAge = 5 * 60 * 1000; // 5 minutos
if (Math.abs(now - timestamp) > maxAge) {
return res.status(401).json({
error: 'Request expired'
});
}
// Agregar server token a la respuesta
res.setHeader('X-Server-Token', generateServerToken());
next();
};
4. CORS Configuración Estricta
import cors from 'cors';
const corsOptions = {
origin: (origin, callback) => {
const allowedOrigins = [
'https://docs.amayo.dev',
'https://amayo.dev'
];
// Permitir requests sin origin (mobile apps, etc)
if (!origin) return callback(null, true);
if (allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: [
'Content-Type',
'Authorization',
'X-Client-Token',
'X-Requested-With',
'X-Timestamp'
],
exposedHeaders: ['X-Server-Token'],
maxAge: 86400 // 24 horas
};
app.use(cors(corsOptions));
5. Ocultar Información del Servidor
// Remover headers que revelan información
app.disable('x-powered-by');
app.use((req, res, next) => {
res.removeHeader('Server');
res.removeHeader('X-Powered-By');
next();
});
6. Sistema de API Keys para el Frontend
En lugar de exponer el endpoint directamente, usar API keys rotativas:
// Generar API key para el frontend (rotar cada 24 horas)
const generateApiKey = () => {
const date = new Date().toISOString().split('T')[0];
const secret = process.env.API_KEY_SECRET;
return crypto
.createHash('sha256')
.update(date + secret)
.digest('hex');
};
// Middleware para validar API key
export const validateApiKey = (req, res, next) => {
const apiKey = req.headers['x-api-key'];
const validKey = generateApiKey();
if (apiKey !== validKey) {
return res.status(401).json({ error: 'Invalid API key' });
}
next();
};
7. Logging y Monitoreo
import winston from '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: 'security.log' })
]
});
// Log de requests sospechosos
export const securityLogger = (req, res, next) => {
const suspicious =
!req.headers['cf-connecting-ip'] ||
!req.headers['user-agent'] ||
req.headers['user-agent'].includes('curl') ||
req.headers['user-agent'].includes('wget');
if (suspicious) {
logger.warn({
type: 'suspicious_request',
ip: req.ip,
headers: req.headers,
path: req.path,
timestamp: new Date()
});
}
next();
};
8. Implementación en el Servidor
// server.js
import express from 'express';
import {
cloudflareOnly,
apiLimiter,
authLimiter,
securityHeaders,
validateSecurityHeaders,
securityLogger
} from './middleware/security.js';
const app = express();
// Aplicar middlewares de seguridad
app.use(securityHeaders);
app.use(cloudflareOnly); // IMPORTANTE: Solo aceptar requests de Cloudflare
app.use(securityLogger);
app.use(validateSecurityHeaders);
// Rate limiting
app.use('/api/', apiLimiter);
app.use('/api/auth/', authLimiter);
// Ocultar endpoint real
app.use('/api', (req, res, next) => {
// No revelar estructura interna en errores
res.locals.showStack = false;
next();
});
// Routes
app.use('/api/auth', authRoutes);
app.use('/api/bot', botRoutes);
// Error handler - no revelar información
app.use((err, req, res, next) => {
logger.error({
error: err.message,
stack: err.stack,
ip: req.ip,
path: req.path
});
res.status(500).json({
error: 'Internal server error',
// No incluir detalles en producción
...(process.env.NODE_ENV === 'development' && {
message: err.message
})
});
});
🔒 Configuración de Variables de Entorno
Frontend (.env)
VITE_DISCORD_CLIENT_ID=your_client_id
VITE_APP_VERSION=1.0.0
# NO incluir URLs del backend aquí
Backend (.env)
PORT=3000
NODE_ENV=production
API_KEY_SECRET=your_random_secret_here
JWT_SECRET=your_jwt_secret_here
DISCORD_CLIENT_SECRET=your_client_secret
ALLOWED_ORIGINS=https://docs.amayo.dev,https://amayo.dev
# Database
DATABASE_URL=your_database_url
# Cloudflare
CLOUDFLARE_API_TOKEN=your_token
📋 Checklist de Seguridad
Frontend ✅
- Servicio de seguridad implementado
- Rate limiting client-side
- No URLs hardcodeadas
- Protección CSRF
- Validación de respuestas
- Sistema de caché
Backend (Por Implementar)
- Verificar requests de Cloudflare
- Rate limiting server-side
- Validación de headers de seguridad
- CORS estricto
- Ocultar información del servidor
- Sistema de API keys
- Logging y monitoreo
- Error handling seguro
Cloudflare
- Bot Fight Mode activado
- Reglas de firewall configuradas
- Rate limiting configurado
- SSL/TLS en modo Full (strict)
- DNSSEC activado
- Page Rules configuradas
🚀 Despliegue
1. Actualizar Cloudflare
# Configurar reglas de firewall
# Dashboard > Security > WAF > Create firewall rule
2. Actualizar el Backend
npm install helmet express-rate-limit cors winston
3. Variables de Entorno
Asegúrate de configurar todas las variables de entorno en producción.
4. Monitoreo
Implementa un sistema de alertas para:
- Intentos de acceso directo a la IP
- Rate limiting excedido
- Errores de seguridad
- Requests sospechosos
📚 Recursos Adicionales
- Cloudflare Security Best Practices
- OWASP Top 10
- Express Security Best Practices
- Content Security Policy
⚠️ Notas Importantes
- Nunca expongas URLs del backend en el código del cliente
- Siempre valida que los requests vengan de Cloudflare
- Usa rate limiting tanto en cliente como en servidor
- Monitorea logs constantemente
- Mantén Cloudflare actualizado con las últimas reglas de seguridad
- Rota API keys regularmente
- Implementa un sistema de alertas
🔄 Mantenimiento
Semanal
- Revisar logs de seguridad
- Verificar rate limiting efectivo
- Actualizar reglas de firewall si es necesario
Mensual
- Rotar API keys
- Actualizar lista de IPs de Cloudflare
- Revisar políticas de CORS
- Auditar accesos sospechosos
Trimestral
- Realizar penetration testing
- Actualizar dependencias de seguridad
- Revisar y actualizar esta guía