Standard Audit
Prepared for Fieldline CRM · April 14, 2026 · CONFIDENTIAL
Fieldline CRM was built over eight months using Cursor and Claude Code by a two-person founding team with no formal engineering background. The product manages contact records, pipeline stages, and email sequences for approximately 40 active customers. We reviewed the full codebase — 63 files, ~8,400 lines of application code.
We identified 2 critical, 4 high, 7 medium, and 11 low/informational findings.
- All application code in src/
- Database schema
- Auth configuration
- API route handlers
- SendGrid, Stripe, HubSpot integrations
- Infrastructure (Vercel config, DNS)
- Mobile app (not in production)
Method: Manual line-by-line review supplemented with static analysis tooling. All findings confirmed by human review before inclusion. Stack: Next.js App Router, Prisma, Supabase (Postgres), SendGrid, Stripe.
The contacts list endpoint filters by userId from the session but does not filter by organizationId. In a multi-tenant deployment where multiple companies share the same database, any authenticated user can enumerate contacts belonging to other organizations by paginating the API response. Confirmed exploitable in the staging environment.
Any customer could view any other customer's contact records. This is a CPRA Section 1798.150 violation and would require mandatory breach notification to affected customers.
Add AND organization_id = $session.organizationId to the contacts query. The organization ID is available in the session JWT and is already validated on login.
A live SendGrid API key was committed to the repository in commit a3f8c2d and has not been rotated despite subsequent .gitignore updates. The key remains accessible in git history. If the repository is ever shared with a diligence reviewer, contractor, or new hire, the key is immediately extractable.
An extracted SendGrid key would allow an attacker to send email from your domain, access email logs, and enumerate recipient addresses — damaging sender reputation and exposing customer data.
Rotate the key in the SendGrid console immediately. Add a pre-commit hook (TruffleHog or git-secrets) to block future credential commits. Scrubbing from git history is advisable if the repo will be shared.
The login endpoint has no rate limiting, CAPTCHA, or lockout logic. An attacker can submit unlimited credential guesses against any account. With a known email address (easily obtained from the contact records exposure above), this enables brute-force account takeover.
Implement rate limiting using Vercel's Edge middleware or an upstash/ratelimit library. Limit to 10 attempts per IP per 15 minutes with exponential backoff.
POST, PATCH, and DELETE handlers do not validate the Origin header or use CSRF tokens. A malicious site could trigger authenticated state mutations by tricking a logged-in Fieldline user into visiting a crafted page.
Add Origin header validation in a shared API middleware layer, or use the csrf package. Apply to all state-mutating routes in a single middleware pass.
HIGH-05, HIGH-06 and 7 medium, 11 low findings documented in Appendix A. Remediation code samples in Appendix B.
The application follows a standard Next.js App Router pattern with Prisma and Postgres. The overall structure is coherent and consistent — evidence that AI tooling, when given a clear architectural prompt, produces navigable code.
The primary systemic issue is that authorization is applied at the user level throughout, with no consistent tenant-scoping layer. This is a common pattern in AI-generated multi-tenant code: the model correctly implements "is this user logged in" but does not independently introduce "does this user belong to the organization that owns this record."
Schema normalization, consistent error shape across API routes, and logical file structure are all strong. The Prisma schema in particular is well-modeled for the domain. These are non-trivial to get right and suggest the founding team gave the AI good architectural context.
- 01Fix CRITICAL-01: add tenant scope filter to all contacts and deals endpoints
- 02Rotate CRITICAL-02 credentials (SendGrid). Audit git history for other exposed keys.
- 03Implement rate limiting on auth endpoints (HIGH-03)
- 04Add CSRF protection to state-mutating routes via shared middleware (HIGH-04)
- 05Review and remediate HIGH-05 and HIGH-06 (documented in Appendix A)
- 06Introduce a withOrganization() middleware wrapper to enforce tenant scope at the route level — prevents recurrence of CRITICAL-01 class issues as the codebase grows
- 07Add pre-commit credential scanning (TruffleHog). Rotate all secrets on a quarterly schedule.