security email is not working.
Severity : High
CVSS : 8.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H)
Endpoint : https://vectorbase.dev/api/cron/auto-retrain
https://vectorbase.dev/api/process
Unauthenticated cron endpoints trigger cross-tenant source reprocessing
Summary
Two internal API routes — /api/cron/auto-retrain and /api/process — are reachable without any authentication because the CRON_SECRET environment variable is not set in production, causing the guarding if condition to short-circuit and skip all auth checks. Any unauthenticated request can trigger source reprocessing across all organizations, and /api/process accepts an arbitrary sourceId with no ownership check, enabling cross-tenant data manipulation.
Steps / PoC
- Confirm the endpoints are publicly reachable without auth:
curl -s https://vectorbase.dev/api/cron/auto-retrain
Response (HTTP 500 — reaches the handler and fails only at DB connection, not at auth):
{"error":"Auto-retrain failed","message":"(ENOTFOUND) tenant/user postgres.zkwujwhzmqbykehvgdhs not found"}
HTTP 200/204 would be returned for any tenant's sources when the DB is reachable.
- Trigger processing of an arbitrary source (no auth, no ownership check):
curl -s -X POST https://vectorbase.dev/api/process \
-H "Content-Type: application/json" \
-d '{"sourceId":"<victim-org-source-uuid>"}'
Response (HTTP 500 — DB unreachable, same handler reached):
{"error":"(ENOTFOUND) tenant/user postgres.zkwujwhzmqbykehvgdhs not found"}
- Root cause in source (
src/app/api/process/route.ts and src/app/api/cron/auto-retrain/route.ts):
const CRON_SECRET = process.env.CRON_SECRET
if (CRON_SECRET && authHeader !== `Bearer ${CRON_SECRET}`) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// proceeed to processSourceWithPrisma(sourceId) without ownership check
When CRON_SECRET is undefined (unset), the && short-circuits and the auth block is never entered. The route continues to call processSourceWithPrisma(sourceId) on any UUID supplied by the caller.
Impact
Any unauthenticated attacker can trigger reprocessing of every source across all tenant organizations (auto-retrain) or force-reprocess a specific target source by UUID, corrupting its embeddings or triggering resource exhaustion on the operator's OpenAI account.
Fix
- Set
CRON_SECRET to a strong random value in the production environment.
- Change the guard to
if (!CRON_SECRET || authHeader !== ...) so an absent secret causes a hard failure, not an open gate.
- Add an ownership check in
/api/process before calling processSourceWithPrisma.
security email is not working.
Severity : High
CVSS : 8.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H)
Endpoint : https://vectorbase.dev/api/cron/auto-retrain
https://vectorbase.dev/api/process
Unauthenticated cron endpoints trigger cross-tenant source reprocessing
Summary
Two internal API routes —
/api/cron/auto-retrainand/api/process— are reachable without any authentication because theCRON_SECRETenvironment variable is not set in production, causing the guardingifcondition to short-circuit and skip all auth checks. Any unauthenticated request can trigger source reprocessing across all organizations, and/api/processaccepts an arbitrarysourceIdwith no ownership check, enabling cross-tenant data manipulation.Steps / PoC
Response (HTTP 500 — reaches the handler and fails only at DB connection, not at auth):
{"error":"Auto-retrain failed","message":"(ENOTFOUND) tenant/user postgres.zkwujwhzmqbykehvgdhs not found"}HTTP 200/204 would be returned for any tenant's sources when the DB is reachable.
Response (HTTP 500 — DB unreachable, same handler reached):
{"error":"(ENOTFOUND) tenant/user postgres.zkwujwhzmqbykehvgdhs not found"}src/app/api/process/route.tsandsrc/app/api/cron/auto-retrain/route.ts):When
CRON_SECRETis undefined (unset), the&&short-circuits and the auth block is never entered. The route continues to callprocessSourceWithPrisma(sourceId)on any UUID supplied by the caller.Impact
Any unauthenticated attacker can trigger reprocessing of every source across all tenant organizations (auto-retrain) or force-reprocess a specific target source by UUID, corrupting its embeddings or triggering resource exhaustion on the operator's OpenAI account.
Fix
CRON_SECRETto a strong random value in the production environment.if (!CRON_SECRET || authHeader !== ...)so an absent secret causes a hard failure, not an open gate./api/processbefore callingprocessSourceWithPrisma.