How I performed a security audit of my own backend.

Here is base checklist to analyse:

  1. Authentication & Session Management

    JWT Strategy: Verify that JwtStrategy correctly extracts the Bearer token from the request headers and validates the sub (user ID) against your database.

    Secret Key Management: Ensure that JWT_SECRET and SUPABASE_JWT_SECRET are not hardcoded but are managed via secure environment variables in your deployment environment.

    Token Expiration: Confirm that JWTs have a reasonable expiration time set in your AuthConfig to minimize the window for token misuse if compromised.

    Supabase Integration: Since you use Supabase for auth, ensure your SupabaseService properly handles the AUTH_CLIENT_OPTIONS and that the service role key is never exposed to the client.

  2. Authorization (RBAC & Ownership)

    RBAC Guard Logic: Audit RbacGuard to ensure it correctly checks both roles and permissions metadata before granting access to controllers.

    Ownership Checks: In IncidentsService, you have logic to check if a user owns an incident before they can update or delete it. Ensure this “Ownership Guard” pattern is consistently applied across all services (e.g., Symptoms, Medications, Triggers).

    Public Decorator: Check all routes marked with @Public() to ensure they are intended to be accessible without authentication.

  3. Data Protection & Encryption

    Symmetric Encryption: Your SymmetricKeyService uses aes-256-cbc for encryption. Verify that:

    - The ENCRYPTION_KEY is exactly 32 bytes.

    - The Initialization Vector (IV) is unique for every encryption operation to prevent pattern matching.

    Hashing: Your IncidentsService uses createHash('sha256'). While SHA-256 is fast, ensure it is being used for data integrity and not for password storage (which Supabase handles).

    Exception Filters: Your AllExceptionsFilter is designed to catch all errors. Ensure that in production mode, it does not leak internal stack traces or database query details to the end-user.

  4. Input Validation & API Security

    Global Validation Pipe: Ensure main.ts has app.useGlobalPipes(new ValidationPipe({ whitelist: true })) enabled to strip any properties from the request body that are not defined in your DTOs.

    CORS Configuration: Review the CORS settings in main.ts. Ensure that only your dashboard domain (https://migrainepulse.com) is allowed in production, rather than using *.

    Helmet/Security Headers: Check if helmet is implemented in main.ts to set security-related HTTP headers (e.g., X-Content-Type-Options, X-Frame-Options).

  5. Infrastructure & Deployment

    Environment Isolation: Confirm that env/.env.example is the only environment file in your repository and that actual .env files are ignored by git.

    Database Connectivity: Ensure your Mongoose connection uses TLS/SSL when connecting to your production MongoDB instance.

    Dependency Audit: Regularly run pnpm audit to check for known vulnerabilities in your project’s dependencies.

    CI/CD Secrets: Verify that secrets like SLIPLANE_API_KEY used in your GitHub Actions are stored as encrypted repository secrets and not in plain text.