Documento de referencia para las medidas de seguridad implementadas tras la auditoría de seguridad (2025).
Regla: El campo balance de una cuenta NUNCA debe ser editable directamente desde el cliente.
- El balance se calcula exclusivamente a partir de
LedgerEntry(libro mayor de doble partida). - En
accountRoutes.ts, elPUT /:idno aceptabalanceen el cuerpo. - Si se requiere reconciliación o ajuste, crear un endpoint específico que genere una transacción de ajuste con auditoría.
Antes de modificar recursos referenciados por FKs (accountId, categoryId, etc.):
- RecurringTransaction:
categoryIdyaccountIdse validan contrauserIden POST y PUT. - UpdateTransaction: Se valida que
accountIdydestinationAccountIdpertenezcan al usuario antes de revertir el impacto financiero. - Loan:
accountIden creación y pago se valida contrauserId. - InstallmentPurchase:
categoryIden PUT se valida contrauserId.
- parseSafeFloat / parseSafeInt: Evitan NaN e Infinity.
- validateAmount / parseAndValidateAmount: Rangos 0.01 .. 999,999,999.99.
- parseAndValidateDate: Rechaza fechas inválidas (NaN) antes de llegar a Prisma.
- validateUuid: Valida formato UUID para parámetros de ruta.
- validateMaxLength / validateDescription / validateName: Límites de longitud para evitar DoS.
- parsePaginationParams: Parámetros de paginación seguros (take 1..500, skip >= 0).
| Campo | Límite | Uso |
|---|---|---|
| amount | 0.01 .. 999M | Transacciones, préstamos, metas |
| description | 2000 caracteres | Transacciones, MSI |
| name | 200 caracteres | Cuentas, categorías, metas |
| notes | 4000 caracteres | Préstamos |
| take / skip | take 1..500, skip≥0 | Paginación |
GET /transactionsyGET /transactions/deleteddevuelven{ data, total, take, skip }.- Default:
take=100, máximotake=500. - Reduce riesgo de DoS por consultas que retornan millones de filas.
- snapshotBalances: Ejecuta en
$transactionpara atomicidad. - generateStatements: Manejo de errores por cuenta (no detiene el job completo).
- Las políticas en
rls-policies.sqlprotegen accesos directos a Postgres (PostgREST, etc.). - El backend usa Prisma con conexión que puede bypassear RLS; la autorización se implementa en capa de aplicación (
where: { userId }en consultas).
- POST /api/notifications/debug-trigger: Solo disponible si
NODE_ENV=developmentoENABLE_DEBUG_NOTIFICATIONS=true. - En producción, el endpoint no se registra; evita creación arbitraria de notificaciones de prueba.
authMiddlewareextrae el JWT del headerAuthorization: Bearer <token>.- Valida con Supabase Auth y establece
req.user = { id, email }. - Todas las rutas de API (excepto
/api/auth/*) pasan porauthMiddleware.
Transaction:@@index([userId, deletedAt, date])para consultas frecuentes filtradas por usuario y estado.- Ejecutar
prisma db pusho crear migración para aplicar cambios enschema.prisma.
backend/prisma/rls-policies.sqlbackend/src/shared/validation.tsbackend/src/shared/security.ts