App Risk
Critical
This app is already live, so Fix now means urgent production risk.
Safety score 0/100
Demo full report
Scanner-generated demo report from an intentionally vulnerable sample repo. The same deterministic rules produce file-level evidence without installing dependencies, running code, or keeping source after the report is built.
App Risk
Critical
This app is already live, so Fix now means urgent production risk.
Safety score 0/100
Code Health
Needs Cleanup
Change risk is visible, but the urgent items are still the safety flows.
Health score 93/100
Test Confidence
Untested
Missing tests matter most when they cover auth, payments, data, admin, uploads, or AI tools.
Test score 10/100
Fix now
12
Fix soon
17
Can wait
2
Source
github.com/abyssguard/sample-vulnerable-ai-saas
Snapshot
10 files / 708 lines
Handling
Source forgotten after report build
This is not seeded marketing copy. It is a deterministic scan of the bundled sample app fixture used to validate the scanner and report UI.
Fix admin access, payment webhook validation, and user-data ownership first. The app is not hopeless, but it is not ready to trust with real users until these flows are checked and re-scanned.
Critical issues appear first. Technical details stay collapsed until needed.
.env:1
Why this matters
Committed environment files often contain API keys, database URLs, or signing secrets.
How to fix
Remove the file from git history if it contains real secrets, rotate exposed keys, and commit only a safe example file.
AI fix prompt
Remove .env from the repository if it contains real secrets. Add a safe .env.example, update .gitignore, and list every key that must be rotated. Do not print secret values in the response.
Evidence
.env is present in the repository file list.
Verify after fixing
Confidence: High. A non-example env file was present in the scanned source tree.
app/api/admin/users/route.ts:3
Why this matters
If middleware does not protect this route, users may be able to read or change data they should not access.
How to fix
Require a server-side session and the right role/ownership check before doing any sensitive work.
AI fix prompt
In app/api/admin/users/route.ts, add a server-side auth check before any data access. Return 401 for missing sessions and 403 when the user lacks permission. Add a focused test for unauthenticated access.
Evidence
Route exports a handler for sensitive-looking data, but no common server-side auth marker was found in the file.
Verify after fixing
Confidence: Medium. No common auth marker was found in the route file. Global middleware may still protect it.
app/admin/page.tsx:1
Why this matters
If middleware is missing or misconfigured, anyone may be able to load admin UI and trigger admin workflows.
How to fix
Require a server-side session and admin-role check in the admin page/layout before rendering admin content.
AI fix prompt
In app/admin/page.tsx, add a server-side session check and admin-role check before rendering admin content. Return or redirect unauthorized users, and add a test proving non-admin users cannot access the page.
Evidence
An admin page route was found without a common server-side auth marker in the page or layout file.
Verify after fixing
Confidence: Medium. The file path is clearly admin-scoped and the page file did not show a common auth marker. Middleware may still protect it.
app/api/stripe/webhook/route.ts:3
Why this matters
Unsigned webhook requests can fake payment, subscription, or account state changes.
How to fix
Verify the provider signature using the raw request body before processing the event.
AI fix prompt
In app/api/stripe/webhook/route.ts, verify the webhook provider signature before updating state. Use the raw request body, reject invalid signatures with 400, and add tests for invalid signatures and duplicate events.
Evidence
Webhook-like handler was found, but common signature verification calls were not detected.
Verify after fixing
Confidence: High. A webhook provider was detected without a common signature verification marker.
app/api/checkout/route.ts:7
Why this matters
Paid access should normally be granted from verified provider events, not from client-controlled requests.
How to fix
Move paid-access state changes behind verified webhooks or server-side provider lookups, and reject direct client attempts to set paid state.
AI fix prompt
Review app/api/checkout/route.ts for payment or subscription state writes. Do not let client input set paid, plan, entitlement, or access state directly. Require a verified provider webhook or server-side provider lookup, and add tests for forged paid-state requests.
Evidence
A non-webhook API route appears to accept request input and write subscription, plan, paid, or access state.
Verify after fixing
Confidence: Medium. The file appears to combine request input with payment/access state writes outside a webhook path.
lib/projects.ts:3
Why this matters
The service role bypasses Supabase RLS. A missing code-level ownership check can expose or mutate every user's data.
How to fix
Use user-scoped Supabase clients for normal user data, keep service-role access in narrow admin/server-only paths, and enforce owner filters plus RLS.
AI fix prompt
Review lib/projects.ts for Supabase service-role usage. Move service-role access behind narrow admin-only server code or replace it with a user-scoped client. Add owner filters and tests proving cross-user records are blocked.
Evidence
A Supabase service-role key appears in code that queries likely user-owned tables.
Verify after fixing
Confidence: High. The file references a Supabase service-role key and likely user-owned table access.
app/api/ai/agent/route.ts:9
Why this matters
Prompt injection or user input can become server-side command execution if tool actions are not strictly isolated.
How to fix
Remove direct shell/code execution from AI routes or replace it with a narrow server-side allowlist of safe operations.
AI fix prompt
In app/api/ai/agent/route.ts, remove direct shell/code execution from the AI tool path. Replace it with explicit safe operations, validate inputs, and add tests proving arbitrary commands are rejected.
Evidence
Command/code execution appears in a route that also handles request or LLM/tool input.
Verify after fixing
Confidence: High. The file combines command/code execution markers with request or tool input markers.
app/api/checkout/route.ts:6
Why this matters
A user may be able to choose a cheaper or unintended price if billing plans are trusted from the browser.
How to fix
Map allowed plans to server-side provider price ids and reject unknown client plan names before creating checkout sessions.
AI fix prompt
In app/api/checkout/route.ts, stop trusting raw price/product ids from the request. Add a server-side allowlist that maps safe plan names to provider price ids, reject unknown plans with 400, and add tests for a forged cheap price id.
Evidence
Checkout-like code reads a price/product id from request input without a visible server-side allowlist.
Verify after fixing
Confidence: Medium. The scanner saw request-controlled price/product input without a common allowlist marker.
app/api/admin/users/route.ts:4
Why this matters
A user may be able to read or change another user's data if ownership is enforced nowhere else.
How to fix
Filter reads and writes by the current user and confirm database-level row policies cover the table.
AI fix prompt
Review app/api/admin/users/route.ts for user-owned data access. Add owner/user filtering or prove database RLS covers the table. Add a test showing user A cannot read user B's records.
Evidence
User-owned data names appear near database queries, but common owner/user filters were not detected in the file.
Verify after fixing
Confidence: Medium. The scanner saw database access to likely user-owned data without an obvious ownership marker.
lib/projects.ts:6
Why this matters
A user may be able to read or change another user's data if ownership is enforced nowhere else.
How to fix
Filter reads and writes by the current user and confirm database-level row policies cover the table.
AI fix prompt
Review lib/projects.ts for user-owned data access. Add owner/user filtering or prove database RLS covers the table. Add a test showing user A cannot read user B's records.
Evidence
User-owned data names appear near database queries, but common owner/user filters were not detected in the file.
Verify after fixing
Confidence: Medium. The scanner saw database access to likely user-owned data without an obvious ownership marker.
app/api/ai/agent/route.ts:14
Why this matters
If users can choose tools or tool definitions, prompt injection can expand what the model is allowed to do.
How to fix
Define server-side tool allowlists and ignore request-provided tool definitions unless they are strictly validated against safe options.
AI fix prompt
In app/api/ai/agent/route.ts, remove request-controlled tool definitions. Define the allowed tools server-side, validate the requested action against an allowlist, and add tests for disallowed tools.
Evidence
LLM tool configuration appears to come from request-controlled data.
Verify after fixing
Confidence: High. A request body value appears to be passed into the LLM tool configuration.
app/api/upload/route.ts:6
Why this matters
Unauthenticated uploads can create storage abuse, malware hosting, surprise bills, or user data exposure.
How to fix
Require a signed-in user before parsing or storing uploaded files, and enforce per-user storage limits.
AI fix prompt
In app/api/upload/route.ts, add server-side authentication before accepting uploads. Return 401 for missing sessions, enforce per-user limits, and add tests for unauthenticated upload rejection.
Evidence
Upload-like API route was found without a common server-side auth marker.
Verify after fixing
Confidence: Medium. No common auth marker was found in an upload-like API route. Middleware may still protect it.
app/api/stripe/webhook/route.ts:3
Why this matters
Payment providers retry webhooks. Duplicate processing can grant access twice, revoke the wrong state, or create inconsistent subscription records.
How to fix
Store provider event ids and skip already-processed events before changing subscription or account state.
AI fix prompt
In app/api/stripe/webhook/route.ts, add webhook idempotency. Store the provider event id before processing state changes, skip duplicate event ids, and add tests for replayed webhook events.
Evidence
Webhook-like handler was found, but no common event-id/idempotency marker was detected.
Verify after fixing
Confidence: Medium. No common idempotency marker was found. The handler may delegate this elsewhere, so verify the call chain.
app/api/upload/route.ts:7
Why this matters
Unrestricted uploads can create storage abuse, malware distribution, or unexpected file execution risk.
How to fix
Limit file size, allowed MIME types/extensions, and storage destination before accepting uploads.
AI fix prompt
In app/api/upload/route.ts, add upload validation for file size, MIME type, and extension. Reject unsupported files before storage and add tests for oversized and wrong-type files.
Evidence
Upload-like code was detected without common file size or content-type checks.
Verify after fixing
Confidence: Medium. The scanner saw upload-like code without obvious validation markers.
app/api/upload/route.ts:10
Why this matters
Private user uploads can leak if stored in public buckets or returned as public URLs without an access check.
How to fix
Store uploads privately by default and serve them through signed URLs or authenticated download routes.
AI fix prompt
In app/api/upload/route.ts, make uploaded files private by default. Replace public URLs with signed URLs or an authenticated download route, and add a test proving another user cannot read the file.
Evidence
Upload-like code references public file access markers.
Verify after fixing
Confidence: Medium. Public access markers were found near upload handling. Confirm whether the files contain user data.
tests/:1
Why this matters
Missing tests are launch-blocking when the flow controls auth, payments, data access, uploads, webhooks, or AI tool execution.
How to fix
Add focused tests proving the admin access flow rejects unsafe input and preserves the expected happy path.
AI fix prompt
Add focused tests for admin access. Cover the unsafe case first, then the normal successful case. Do not call real external services.
Evidence
A admin access flow was detected, but scanned test files did not reference it.
Verify after fixing
Confidence: High. No scanned test files were found for this critical flow.
tests/:1
Why this matters
Missing tests are launch-blocking when the flow controls auth, payments, data access, uploads, webhooks, or AI tool execution.
How to fix
Add focused tests proving the webhook signature handling flow rejects unsafe input and preserves the expected happy path.
AI fix prompt
Add focused tests for webhook signature handling. Cover the unsafe case first, then the normal successful case. Do not call real external services.
Evidence
A webhook signature handling flow was detected, but scanned test files did not reference it.
Verify after fixing
Confidence: High. No scanned test files were found for this critical flow.
tests/:1
Why this matters
Missing tests are launch-blocking when the flow controls auth, payments, data access, uploads, webhooks, or AI tool execution.
How to fix
Add focused tests proving the user data ownership flow rejects unsafe input and preserves the expected happy path.
AI fix prompt
Add focused tests for user data ownership. Cover the unsafe case first, then the normal successful case. Do not call real external services.
Evidence
A user data ownership flow was detected, but scanned test files did not reference it.
Verify after fixing
Confidence: High. No scanned test files were found for this critical flow.
tests/:1
Why this matters
Missing tests are launch-blocking when the flow controls auth, payments, data access, uploads, webhooks, or AI tool execution.
How to fix
Add focused tests proving the AI tool/input execution flow rejects unsafe input and preserves the expected happy path.
AI fix prompt
Add focused tests for AI tool/input execution. Cover the unsafe case first, then the normal successful case. Do not call real external services.
Evidence
A AI tool/input execution flow was detected, but scanned test files did not reference it.
Verify after fixing
Confidence: High. No scanned test files were found for this critical flow.
tests/:1
Why this matters
Missing tests are launch-blocking when the flow controls auth, payments, data access, uploads, webhooks, or AI tool execution.
How to fix
Add focused tests proving the file upload handling flow rejects unsafe input and preserves the expected happy path.
AI fix prompt
Add focused tests for file upload handling. Cover the unsafe case first, then the normal successful case. Do not call real external services.
Evidence
A file upload handling flow was detected, but scanned test files did not reference it.
Verify after fixing
Confidence: High. No scanned test files were found for this critical flow.
package.json:2
Why this matters
Users need a controlled way to verify fixes for auth, payments, data access, uploads, webhooks, and AI tools.
How to fix
Add a focused test script and at least one critical-flow regression test before relying on the report as fixed.
AI fix prompt
In package.json, add a test script that runs the project's test runner. Then add focused tests for the highest-risk AbyssGuard finding without calling real external services.
Evidence
Critical app flows were detected, but package.json has no test-like script.
Verify after fixing
Confidence: High. package.json was parsed and no test-like script name was present.
lib/projects.ts:1
Why this matters
If code-level ownership checks are missed, RLS is the database backstop that prevents cross-user data exposure.
How to fix
Add or verify Supabase migrations that enable RLS and create owner-based policies for user-owned tables.
AI fix prompt
Inspect Supabase migrations for user-owned tables. Add `enable row level security` and owner-based `auth.uid()` policies where missing, then add tests for cross-user access denial.
Evidence
Supabase user-data access was detected, but scanned SQL migrations did not show row-level security policies.
Verify after fixing
Confidence: Needs manual review. Migrations may live outside the scanned source cap, but no RLS policy file was visible in this snapshot.
app/api/ai/agent/route.ts:2
Why this matters
Unvalidated AI inputs can leak data, trigger unsafe tools, or make the model act on attacker-controlled instructions.
How to fix
Validate request shape, limit what data reaches the model, and allowlist any tools the model can call.
AI fix prompt
In app/api/ai/agent/route.ts, validate the request body before calling the LLM. Add an allowlist for tools/actions and avoid sending private data unless explicitly required.
Evidence
LLM/API usage appears near request input, but common validation or allowlist markers were not found.
Verify after fixing
Confidence: Medium. The route appears to connect user input to an LLM without a visible validation marker.
app/api/upload/route.ts:9
Why this matters
User-controlled filenames can overwrite files, leak names, or create path traversal and cache confusion risks.
How to fix
Generate server-side object keys with random ids, preserve extensions only after validation, and store the original name as metadata.
AI fix prompt
In app/api/upload/route.ts, stop using the original filename as the storage key. Generate a random server-side key, validate the extension/MIME type, and add tests for duplicate and path-like filenames.
Evidence
The upload path appears to use the original filename without a visible randomization or sanitization marker.
Verify after fixing
Confidence: Medium. Original filename usage was found without obvious sanitization or random id generation.
app/api/admin/users/route.ts:3
Why this matters
Expensive or sensitive routes can be abused for spam, cost spikes, brute force attempts, or degraded service.
How to fix
Add a simple per-IP or per-user rate limit around this route.
AI fix prompt
Add a simple rate limit to app/api/admin/users/route.ts. Keep the existing response shape for successful requests and return 429 when the limit is exceeded.
Evidence
High-risk route keywords were detected, but common rate-limit markers were not found.
Verify after fixing
Confidence: Medium. A route looked sensitive or expensive and no rate-limit marker was visible.
app/api/stripe/webhook/route.ts:3
Why this matters
Expensive or sensitive routes can be abused for spam, cost spikes, brute force attempts, or degraded service.
How to fix
Add a simple per-IP or per-user rate limit around this route.
AI fix prompt
Add a simple rate limit to app/api/stripe/webhook/route.ts. Keep the existing response shape for successful requests and return 429 when the limit is exceeded.
Evidence
High-risk route keywords were detected, but common rate-limit markers were not found.
Verify after fixing
Confidence: Medium. A route looked sensitive or expensive and no rate-limit marker was visible.
app/api/checkout/route.ts:5
Why this matters
Expensive or sensitive routes can be abused for spam, cost spikes, brute force attempts, or degraded service.
How to fix
Add a simple per-IP or per-user rate limit around this route.
AI fix prompt
Add a simple rate limit to app/api/checkout/route.ts. Keep the existing response shape for successful requests and return 429 when the limit is exceeded.
Evidence
High-risk route keywords were detected, but common rate-limit markers were not found.
Verify after fixing
Confidence: Medium. A route looked sensitive or expensive and no rate-limit marker was visible.
app/api/ai/agent/route.ts:6
Why this matters
Expensive or sensitive routes can be abused for spam, cost spikes, brute force attempts, or degraded service.
How to fix
Add a simple per-IP or per-user rate limit around this route.
AI fix prompt
Add a simple rate limit to app/api/ai/agent/route.ts. Keep the existing response shape for successful requests and return 429 when the limit is exceeded.
Evidence
High-risk route keywords were detected, but common rate-limit markers were not found.
Verify after fixing
Confidence: Medium. A route looked sensitive or expensive and no rate-limit marker was visible.
app/api/upload/route.ts:6
Why this matters
Expensive or sensitive routes can be abused for spam, cost spikes, brute force attempts, or degraded service.
How to fix
Add a simple per-IP or per-user rate limit around this route.
AI fix prompt
Add a simple rate limit to app/api/upload/route.ts. Keep the existing response shape for successful requests and return 429 when the limit is exceeded.
Evidence
High-risk route keywords were detected, but common rate-limit markers were not found.
Verify after fixing
Confidence: Medium. A route looked sensitive or expensive and no rate-limit marker was visible.
app/dashboard/page.tsx:1
Why this matters
Size alone is not a bug, but a large file that mixes critical concerns is harder to safely analyze, modify, and test.
How to fix
Extract the highest-risk concerns first, such as auth, billing, data access, or UI rendering, while preserving behavior.
AI fix prompt
Refactor app/dashboard/page.tsx in small steps. Keep behavior unchanged. Extract one critical concern at a time, add tests around the moved logic, and avoid broad UI redesigns.
Evidence
app/dashboard/page.tsx has about 620 lines and mixes billing/payment, user data concerns.
Verify after fixing
Confidence: High. The file has concrete size and multiple critical-concern signals; this is change-risk evidence, not authorship detection.
.github/workflows/:1
Why this matters
Without CI, risky changes can land without tests, typecheck, or lint running automatically.
How to fix
Add a small CI workflow that runs install, typecheck/build, and focused tests for critical flows.
AI fix prompt
Add a minimal GitHub Actions workflow for this app. It should install dependencies, run typecheck or build, and run the critical-flow tests. Keep secrets out of pull_request workflows.
Evidence
Critical app flows were detected, but no GitHub Actions workflow files were visible in the scanned snapshot.
Verify after fixing
Confidence: Needs manual review. CI may exist outside GitHub Actions or outside the scanned source cap, but no workflow file was visible.
Paid scans store this prompt in the report so users can paste it into their AI coding tool.
You are fixing an AI-built app based on an AbyssGuard scanner-generated demo report. Goal: Fix the Fix now issues first without broad refactors. Fix order: 1. Environment file appears committed (.env:1) 2. Sensitive API route has no visible auth check (app/api/admin/users/route.ts:3) 3. Admin page has no visible server-side access gate (app/admin/page.tsx:1) 4. Webhook handler may be missing signature verification (app/api/stripe/webhook/route.ts:3) 5. Subscription state may be updated outside a verified webhook (app/api/checkout/route.ts:7) 6. Supabase service role key touches user-owned data (lib/projects.ts:3) Constraints: - Do not redesign unrelated UI. - Do not rename routes unless required. - Do not print or store secret values. - Keep each change small and explain what changed. - Add or update focused tests before marking the issue fixed. After fixes: - Run relevant tests locally. - Manually verify auth, admin, payment/webhook, user data, uploads, and AI tool flows if present. - Re-scan with AbyssGuard.
Plain-English disclaimer: AbyssGuard reduces launch and production risk, but no static report can prove an app is secure. Use this as a prioritized technical review, not a guarantee.