El endpoint de login construye la query SQL concatenando directamente el email del usuario sin parametrizar. Un atacante puede enviar email = "' OR '1'='1" y autenticarse sin contraseña, o ejecutar queries arbitrarias.
Escenario de fallo: POST /api/auth/login con body {"email": "' OR 1=1--", "password": "x"} devuelve el primer usuario de la BD con sesión válida. No hay ORM ni validación de esquema que lo intercepte.
Usar siempre queries parametrizadas ($1, $2... con pg). Nunca interpolar variables en strings SQL. Considerar usar un query builder (Drizzle, Knex) que parametrice automáticamente.
La clave del servicio de email (SendGrid) está hardcodeada como string literal. Esta clave ya está en git history y debe revocarse inmediatamente, independientemente del fix que se aplique ahora.
Escenario de fallo: Cualquier persona con acceso al repositorio (o que pueda leer el historial git) obtiene acceso total al servicio de email. Riesgo inmediato de abuso para enviar phishing o incurrir en costes elevados.
1. Revocar la key en el panel de SendGrid ahora. 2. Crear nueva key y añadir a variables de entorno (.env.local, no versionado). 3. Añadir .env* a .gitignore. 4. Hacer git filter-branch o BFG para purgar el historial.
El endpoint GET /api/users hace SELECT * FROM users sin paginación. Con 10.000 pacientes en la tabla, cada petición a este endpoint cargará toda la tabla en memoria, causando OOM o timeouts en producción.
El useEffect que carga los usuarios no incluye clinicId en su array de dependencias. Si el dietista cambia de clínica en el mismo session, el componente no re-fetching y muestra los pacientes de la clínica anterior.
Los errores del bloque catch son reenviados directamente al cliente con error.message. Errores de base de datos o stack traces con rutas internas del servidor quedan expuestos al navegador. Facilita el fingerprinting de la infraestructura.
Se usa el index i como key en el listado de pacientes. Como la lista puede ordenarse por nombre/fecha, React no podrá rastrear correctamente los elementos causando renders incorrectos o pérdida del estado local de cada card.
Hay tres console.log de desarrollo activos que imprimen objetos de usuario (incluyendo emails) en el log del servidor de producción. Esto puede violar GDPR al persistir datos personales en logs no controlados.
Hay TODOs sueltos (// TODO: add rate limiting, // TODO: pagination) sin número de ticket. En 3 meses nadie sabrá cuáles están resueltos. Añadir referencia o crear ticket y linkarlo.
La función export async function updateUser() tiene 4 parámetros opcionales con semántica no obvia. Una doc mínima evitaría preguntas al autor.
data, res2, tmp con nombres poco descriptivosNaming genérico en contextos no triviales. Renombrar a patientRecord, updatedUser, etc. facilita el mantenimiento.