express-rate-limit: 100 req/IP por ventana de 15 min
Origenes permitidos, credenciales habilitadas, metodos restringidos
Auto-sanitize de strings, XSS neutralizado, recursivo en objetos
AES-256-GCM para secrets, clave desde env, permisos 0o600
Headers de seguridad HTTP, trust proxy, config produccion
Winston: error.log, combined.log, quickbooks.log con contexto QB
| Control | Detalle |
|---|---|
| Rate Limiting | express-rate-limit — 100 peticiones por IP en ventana de 15 minutos |
| CORS | Origenes: localhost:3000, apiqb.admindual.com, developer.intuit.com, oauth.platform.intuit.com |
| Sanitizacion | XSS: & < > " ' / neutralizados. Recursivo en objetos. Rutas excluidas para APIs externas |
| Encriptacion | AES-256-GCM en .organization-secrets con IV aleatorio de 16 bytes |
| Payload | Limite de 10kb en body. Timeouts configurados por ruta |
| DELETE | Todas las rutas DELETE protegidas con API Key + logging + validacion SyncToken |
| Errores | Try-catch global, codigos HTTP especificos, info sensible nunca expuesta |
// Encriptacion de secrets const algorithm = 'aes-256-gcm'; const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv(algorithm, key, iv); // Archivo .organization-secrets con permisos 0o600
| Componente | Detalle |
|---|---|
| Access Token | Expira cada 1 hora, auto-refresh en respuesta 401 (1 solo retry) |
| Refresh Token | Valido 100 dias. Si expira, re-auth manual via /connect/:org |
| Secrets | AES-256-GCM, archivo con permisos 0o600, clave desde ENCRYPTION_KEY |
| OAuth2 | Flujo Authorization Code con intuit-oauth SDK |
Middleware validateApiKey protege 11 rutas. Se valida via header X-API-Key contra variable de entorno.
const validateApiKey = (req, res, next) => {
const apiKey = req.headers['x-api-key'];
if (!apiKey || apiKey !== process.env.API_KEY) {
return res.status(401).json({
success: false,
error: 'API key no valida'
});
}
next();
};
| Variable | Proposito |
|---|---|
QUICKBOOKS_CLIENT_ID | ID de la app OAuth en Intuit |
QUICKBOOKS_CLIENT_SECRET | Secret de la app OAuth |
ENCRYPTION_KEY | Clave para AES-256-GCM de secrets |
API_KEY | Clave para proteger endpoints de la API |
| Validacion | Detalle |
|---|---|
| Payload size | Limite de 10kb en request body |
| Timeouts | Configurados por ruta individual |
| Fechas | Formato YYYY-MM-DD validado |
| Auth state | Estado de autenticacion verificado antes de operaciones QB |
| SyncToken | Requerido en updates/deletes para evitar conflictos |
| Advertencia | Estado | Accion |
|---|---|---|
| Sanitizacion de caracteres especiales | Parcialmente implementado | Mejorar para caracteres adicionales |
| Helmet completo | Instalado, no totalmente configurado | Activar todas las protecciones de headers |
| NODE_ENV en produccion | Falta configurar | Establecer NODE_ENV=production |
[ ] Certificados SSL/TLS configurados [ ] Firewall y restricciones de IP [ ] Monitoreo en tiempo real [ ] Backups automaticos de logs y config [ ] Plan de respuesta a incidentes [ ] Pruebas de penetracion regulares [ ] Escaneo de vulnerabilidades automatico