Evaluación de vulnerabilidades del CRM externo open-source y del CRM PHP propio. Recomendación de adopción y plan de acción para reforzar la seguridad actual.
CRM open-source orientado a agentes IA. Stack moderno: TypeScript · Bun · Next.js · NestJS · Prisma · Postgres. Diseñado para equipos de ventas B2B con integración de email (Gmail/Outlook). No es compatible con tu caso de uso (WhatsApp/Meta webhooks, Hostinger, PHP).
CRM PHP custom con soporte WhatsApp, Facebook Messenger, Instagram DM. Funcional y adaptado al negocio. Tiene 3 vulnerabilidades críticas que deben corregirse antes de continuar en producción.
ALLOWED_SIGN_IN no está configurado.
NODE_ENV=production.
Todo usuario autenticado puede leer y escribir todos los registros. No hay roles, permisos por registro ni organizaciones. Si hay más de un operador, todos ven todo.
Gmail/Calendar access es condición del sign-in. El agente lee cuerpos de mensajes y asistentes de reuniones de personas que no se registraron en el CRM. Tú eres el data controller.
Perplexity, LinkedIn y otros vendors reciben nombres, dominios de email y empleadores si se configuran sus API keys. Sin keys, solo salen llamadas a Google APIs.
El agente usa eve (framework Vercel propio). El runtime de durable sessions depende de la infraestructura de Vercel. Difícil de migrar a Hostinger.
Sí se pueden adoptar sus patrones de diseño (work queue, evidence ledger, agent skills) adaptados a PHP.
"admin"
La contraseña del CRM está literalmente en el código fuente como $crm_password = "admin".
Cualquiera que acceda al repositorio (o que pruebe contraseñas triviales) tiene acceso completo al CRM.
En .env: CRM_PASSWORD=tu_contraseña_segura_aqui
El archivo install.php ejecuta init.sql sin ninguna verificación de autenticación.
Cualquier visitante puede hacer una petición GET y reinicializar (destruir) la base de datos.
Este archivo no debe existir en producción.
install.php.disabled en producción.
O agregar require_login(); al inicio del archivo y un confirm antes de ejecutar.
El formulario de login no tiene ningún mecanismo anti-bruta-fuerza: ni delay, ni captcha, ni bloqueo por intentos. Un atacante puede probar miles de contraseñas automáticamente sin limitación.
login.php establece $_SESSION['logged_in'] = true sin llamar primero a session_regenerate_id(true). Un atacante que inyecte un session ID previo mantiene acceso.
El formulario POST de login.php no valida ningún token CSRF. Un atacante puede crear un formulario externo que haga login con credenciales conocidas.
En varios endpoints (send_message.php, webhook.php) el catch genérico imprime $e->getMessage() directamente en la respuesta JSON. Puede revelar rutas de servidor, configuración interna o credenciales.
El parser manual del .env no soporta valores entre comillas (KEY="valor con espacios") ni escapes. Valores complejos (contraseñas con =, URLs) se truncan silenciosamente.
hash_equals()
Comparación en tiempo constante para el token, protege contra timing attacks.
send_message.php y otros usan $pdo->prepare() — protegido contra SQL injection.
Valida X-Hub-Signature-256 de Meta antes de procesar cualquier payload.
require_login() en endpoints críticos
send_message.php y otros endpoints sensibles verifican sesión activa.
htmlspecialchars() en outputs HTML
login.php escapa el mensaje de error con htmlspecialchars — protegido contra XSS reflejado.
trycompai/crm es seguro y bien diseñado como producto, pero es incompatible con tu infraestructura (Hostinger + PHP + WhatsApp/Meta). No es una mejora — es una plataforma completamente diferente. Mantén tu CRM PHP y corrije las 3 vulnerabilidades críticas.
.env como CRM_PASSWORD. Desactivar install.php en producción (chmod 000 o mover fuera de public/).
session_regenerate_id(true) en login. Agregar token CSRF al formulario. Agregar rate limiting (5 intentos / 10 min) en login.php.
vlucas/phpdotenv via Composer.
Su claimDue con FOR UPDATE SKIP LOCKED evita duplicados cuando hay múltiples workers. Aplica a tu cola WhatsApp → GoPlay.
Nunca guardar datos deducidos como hechos. Solo lo observado explícitamente. Patrones sólidos para AIService.
Skills versionadas con el código. Tu AIService puede leer un system_prompt.md versionado en lugar de tenerlo hardcodeado en PHP.
| Control | trycompai/crm | WhatsApp CRM (PHP) |
|---|---|---|
| Auth segura (no contraseña simple) | ✓ OAuth Google/Microsoft | ✗ "admin" hardcodeado |
| Protección SQL Injection | ✓ Prisma ORM | ✓ PDO + prepared statements |
| Protección XSS | ✓ React (escaping automático) | ⚠ Parcial (htmlspecialchars en login, no en otros) |
| Protección CSRF | ✓ Better Auth | ✗ Sin token CSRF |
| Rate limiting login | ✓ Better Auth built-in | ✗ Sin protección |
| Webhooks con firma HMAC | N/A (sin webhooks) | ✓ hash_equals + Meta X-Hub-Signature |
| Archivos de instalación protegidos | ✓ No hay install scripts públicos | ✗ install.php accesible sin auth |
| Session fixation protegida | ✓ Better Auth | ✗ Sin session_regenerate_id() |
| HTTPS en producción | ✓ Obligatorio | ✓ Hostinger SSL activo |
| Secretos en variables de entorno | ✓ .env.example sin valores reales | ✗ Contraseña en código fuente |