Security Report
Self-Assessed Security Report
This report covers the results of a security assessment run against the PromptUnit.ai production codebase. It includes an automated dependency scan (npm audit) and a manual OWASP Top 10 review of application code.
Date
2026-05-01
Scope
promptunit.ai
Methodology
npm audit + OWASP Top 10
Assessed by
Internal team
Executive Summary
Critical
0
High
4 → 0 fixed
Moderate
6 accepted
No critical or high vulnerabilities remain open.
4 HIGH severity issues in the Clerk authentication library were fixed during this audit via a non-breaking dependency upgrade. 6 MODERATE issues in transitive dependencies are accepted as non-exploitable in the PromptUnit production code path. OWASP Top 10 review found no application-level failures.
Dependency Scan — npm audit
Scan date: 2026-05-01. Node.js 20, npm 10.
GHSA-w24r-5266-9c3cAuthorization bypass when combining organization, billing, or reverification checks
@clerk/nextjs, @clerk/backend, @clerk/react, @clerk/shared
npm audit fix — upgraded all Clerk packages in place, no breaking changes
GHSA-qx2v-qp2m-jg93XSS via unescaped </style> in CSS stringify output
postcss <8.5.10
Transitive dep inside Next.js build toolchain. Only runs server-side during build, never in a browser context. Fix requires downgrading Next.js to v9 — not viable. Not exploitable in our deployment.
GHSA-p7fg-763f-g4gfInsecure default file permissions in Local Filesystem Memory Tool
@anthropic-ai/sdk 0.79.0–0.91.0
Affects the SDK's optional filesystem memory feature, which is not used in this codebase. The SDK is used only for its inference client. Not exploitable.
GHSA-92pp-h63x-v22mMiddleware bypass via repeated slashes in serveStatic
@hono/node-server <1.19.13
Transitive dep pulled in by @prisma/dev (a Prisma internal toolchain package). Not present in the production build — Prisma is not used as an ORM in this project. Not exploitable.
GHSA-w5hq-g745-h8pqMissing buffer bounds check in v3/v5/v6 when buf is provided
uuid <14.0.0
Transitive dep via svix (Clerk webhook verification library). The affected code path (passing a custom buf argument to uuid) is not called anywhere in the codebase. Not exploitable.
OWASP Top 10 — Manual Review
Manual code review against OWASP Top 10 (2021 edition).
Broken Access Control
PASSAll dashboard and API routes protected via Clerk session middleware. Supabase RLS enforced on all tables. Admin routes additionally gated by ADMIN_USER_IDS env var. Cron and webhook endpoints use timingSafeEqual token comparison. No unauthenticated access to user data confirmed.
Cryptographic Failures
PASSProvider API keys encrypted at rest with AES-256-GCM (ENCRYPTION_KEY in Vercel, never in code). PromptUnit API keys stored as HMAC-SHA256 hashes — raw key is unrecoverable from the database. timingSafeEqual used on all secret comparisons (cron tokens, webhook tokens). TLS enforced in transit by Vercel edge.
Injection
PASSAll database queries use the Supabase JavaScript SDK with parameterized calls — no raw SQL concatenation anywhere. Blog HTML is generated by remark-html from markdown files committed to the repository (author-controlled only, not user input). No eval() or Function() constructor found in the codebase.
Insecure Design
PASSRouting is opt-in after 14-day observation period — no traffic is modified without explicit user action. Billing model (20% of verified savings) removes any incentive for the system to route incorrectly. Spend circuit breaker enforces hourly and daily hard limits per organization.
Security Misconfiguration
PASSCORS wildcard is intentional on /api/proxy/* routes — customers call the proxy from their own web apps and the PromptUnit key is a server-side secret, not a browser credential. This is documented in a code comment. All environment secrets are in Vercel — none hardcoded. No debug or admin endpoints exposed without authentication.
Vulnerable and Outdated Components
PARTIAL4 HIGH (Clerk) fixed during this audit. 6 MODERATE remaining — all in transitive dependencies not present in the production code path (see npm audit table above). No critical vulnerabilities remain. Accepted risk is documented per finding.
Authentication Failures
PASSAuthentication delegated to Clerk (production mode). Session tokens managed by Clerk — not stored in local state or localStorage. Rate limiting enforced on all proxy routes via checkRateLimit(). No credential enumeration vector identified.
Software and Data Integrity Failures
PASSNo eval(), no CDN-hosted scripts without integrity attributes, no deserialization of untrusted data. Build pipeline runs on Vercel from a locked package-lock.json. No dynamic code execution paths identified.
Security Logging and Monitoring
PASSEvery proxy call is logged to Supabase (model, cost, latency, routing decision, task type). BetterStack monitors /api/health every 60 seconds with alerting to igal@promptunit.ai. Admin alert email triggered on BetterStack downtime webhook. Security audit routine runs every 4 days via Claude CCR.
Server-Side Request Forgery
PASSAll upstream provider URLs are derived from a hardcoded map in provider-endpoints.ts — no user-supplied URL is ever fetched. The proxy accepts a model name from the request body, maps it to a known provider endpoint internally, and rejects any model not in the known list.
Scope and Limitations
In scope: Next.js application code (src/), API routes, middleware, server-side libraries, npm dependency tree.
Out of scope: Supabase infrastructure (assessed separately by Supabase), Clerk identity infrastructure (assessed by Clerk), Vercel hosting infrastructure (assessed by Vercel), physical security.
Limitations: This is a self-assessed report, not a third-party penetration test. It does not include dynamic application scanning (DAST) or fuzzing. A third-party pentest is planned as part of SOC 2 Type I preparation.
Questions about our security practices?
Contact us at security@promptunit.ai
← Back to Trust & Security