Skip to content

Security Audit - Resolution Tracker

Audit date: 2026-05-20 Resolution completed: 2026-05-23 Auditor: Internal review Phase: 5.5


Summary

Severity Total Resolved Remaining
Critical 4 4 0
High 1 1 0
Medium 4 4 0
Low 2 2 0
Total 11 11 0

Resolution details

# Finding Severity Issue Status
1 Tenant :id param vs x-tenant-id mismatch - cross-tenant mutation Critical #140 ✅ Fixed
2 User update endpoint allows any user to modify any profile Critical #141 ✅ Fixed
3 No PlatformAdminGuard - any user can mutate billing catalog Critical #142 ✅ Fixed
4 No rate limiting - auth brute force and DoS trivial Critical #143 ✅ Fixed
5 Refresh token findUniqueOrThrow fails open on purged tokens High #144 ✅ Fixed
6 Cancel endpoint doesn't update status to CANCELLED Medium #145 ✅ Fixed
7 Consume endpoint doesn't persist usage events Medium #146 ✅ Fixed
8 Audit log shallow sanitization + no size limit Medium #147 ✅ Fixed
9 Billing ledger endpoints missing RolesGuard Medium #148 ✅ Fixed
10 Invoices controller direct Prisma queries Low #149 ✅ Fixed
11 process.env.PORT, missing pagination, duplicate comment Low #150 ✅ Fixed

Verification checklist

  • [x] Cross-tenant mutation: PATCH tenant with mismatched header/param returns 403
  • [x] User update: DEVELOPER cannot update other users, self-update works, isActive requires OWNER
  • [x] Platform admin: non-admin gets 403 on plan/feature/entitlement/price mutations
  • [x] Rate limiting: 11th login attempt returns 429 with Retry-After header
  • [x] Refresh token: purged token returns 401, not 500
  • [x] Subscription cancel: status changes to CANCELLED, not just cancelledAt
  • [x] Consume persistence: usage_event row created with source=consume-endpoint
  • [x] Audit sanitization: nested passwords redacted, Date fields serialize as ISO strings
  • [x] Billing roles: DEVELOPER gets 403 on ledger/balance/payments endpoints
  • [x] Invoice service: controller has no PrismaService import, generate throws NotFoundException
  • [x] Misc: app uses ConfigService for PORT, subscriptions/api-keys have pagination

Security posture after Phase 5.5

What's protected

  • Tenant isolation: URL param validated against header on tenant mutations
  • User authorization: self-update vs admin-update with role checks
  • Catalog integrity: only platform admins can mutate plans/features/entitlements/prices
  • Brute force prevention: IP-based rate limiting on auth endpoints
  • Financial data access: OWNER/ADMIN/BILLING roles required for billing endpoints
  • Audit integrity: recursive sanitization, size limits, no sensitive data in logs
  • Billing correctness: cancelled subscriptions stop generating invoices, consumed usage is durable

Known limitations (future phases)

  • Rate limiting is fixed-window, not sliding window (2x burst at boundaries)
  • Auth rate limit fails open on Redis errors (should fail closed)
  • No IP blocklist or ban after repeated failures
  • No CSRF protection (API-only, no browser forms)
  • No request body size limit at application level (rely on nginx/reverse proxy)
  • Webhook signature validation depends on provider adapter correctness