Inspiration
Everyone is shipping AI apps, and almost nobody checks them properly. Small teams don't have a QA department, a security team, or a red team, and AI adds new ways to fail: leaked system prompts, prompt injection, one user's data showing up in another user's chat, model output that runs as code in the browser. We wanted one check that any team could run on any AI project and that answers a simple question in plain language: is this safe to ship, and if not, what exactly is wrong?
What it does
Upload a project (archive, folder, or GitHub repo) and Cybercheck runs four checks on it, each in a disposable sandbox with outbound network turned off:
- Testing: starts the app, sets up test data, and checks that features actually work, including AI-written checks based on the project's own docs and tests.
- Security: scans for weaknesses and proves the real ones with safe, synthetic attacks.
- AI Evaluator: tests the AI parts for leaked secrets, prompt injection, cross-user isolation, unsafe tool use, and unsafe rendering, using a real browser canary.
- AI Adversarial: attacks the app the way a real attacker would, chaining weaknesses into multi-step attacks against synthetic users and data.
Every result comes with evidence. A finding is only "confirmed" when the attack is reproduced, not because a model said so.
When a problem is confirmed, a human reviews it and can click Try repair in sandbox. An AI proposes a small patch, the patch runs in fresh sandboxes, the exact failing attack and its neighbours are rerun, and the fix is marked verified only if:
$$\text{verified} \iff \forall r \in R:\ r_{\text{after}} = \text{pass} \ \land\ \forall g \in G:\ g_{\text{before}} = \text{pass} \Rightarrow g_{\text{after}} = \text{pass}$$
where $R$ is the attacks that reproduced the problem and $G$ is the checks that passed before. Your code is never changed automatically. You get a verified diff to apply yourself.
How we built it
- Frontend: Next.js and React with Tailwind, a plain-language results page for non-technical users, and full evidence for engineers.
- Backend: a Fastify API in TypeScript with PostgreSQL and Drizzle, and shared zod contracts between web and API.
- Code understanding: tree-sitter parses JavaScript, TypeScript and Python to map routes, auth guards, data models and AI components.
- Sandboxes: Docker locally and Nebius in the cloud. Every run is isolated, with no outbound network, synthetic identities, and loopback canaries.
- AI: Gemini and Nebius models plan app start-up, write checks, and propose patches. Deterministic oracles, not the model, decide every verdict.
- Quality: more than 660 API tests with Vitest, Playwright end-to-end tests, and frozen benchmark projects with planted vulnerabilities and fixed twins.
Challenges we ran into
- Keeping "verified" honest. A correct fix for unsafe HTML rendering removed the HTML sink, so our browser test stopped running and the fix could never be proven. We changed repair reruns to replay the original attack plan against the patched app, so "verified" always rests on a real browser seeing the payload stay inert.
- One test, many bugs. A single AI test case could fail for three different defects at once, so fixing one never made it pass. We now judge each defect on its own.
- Never leaking secrets to the model. Code sent to the repair model is redacted. That broke edits on lines that contained a secret, so we built a safe way to match those lines back to the real file without the secret ever leaving the server.
- Setting up real users. Credentials found in test files often exist only inside that test's database. We learned to tell runtime accounts apart from test-only ones.
Accomplishments that we're proud of
- On our repair benchmark (3 test apps, 3 full runs, real AI patches), 94 of 96 repairs verified (98%), with zero false "verified" results, zero regressions, zero unauthorized edits, and the original code unchanged in every run.
- Detection works fully without AI credits. AI makes it smarter but never decides a verdict.
What we learned
The model is the easy part. The hard part is the evidence: proving an attack really ran, proving a fix really worked, and saying "inconclusive" instead of guessing. Every honest "we could not test this" made the product more trustworthy.
What's next
- Smarter test-data setup across more frameworks, so every attack reaches its target.
- Exact, frozen attack plans so reruns always repeat the same attacks.
- A GitHub app that runs Cybercheck on every pull request.
Built With
- better-auth
- docker
- drizzle-orm
- fastify
- gemini
- github-api
- mermaid
- nebius
- next.js
- node.js
- playwright
- postgresql
- python
- react
- recharts
- tailwindcss
- tree-sitter
- typescript
- vitest
- zod
Log in or sign up for Devpost to join the conversation.