Inspiration

Professional penetration testing costs between $10,000 and $50,000 and takes weeks to complete. The result is that most startups and small teams ship to production having never had their security tested, not because they don't care, but because the barrier is too high. The bugs are always the same ones: SQL injection, cross-site scripting, broken access control. The OWASP Top 10 hasn't changed much in 20 years, yet these vulnerabilities still make headlines every week.

We wanted to build the thing that makes professional security testing accessible to everyone. Not a static scanner that pattern-matches HTML, but an actual agent that thinks, probes, and reasons about vulnerabilities the way a human pentester would.

What it does

Phantom is an autonomous AI red-team agent. You give it a URL. It finds every vulnerability.

  • Recon — A real headless Chromium browser crawls the target application, mapping every page, form, API endpoint, cookie, and response header. Google Gemini parses the HTML to build a structured attack surface.
  • Attack — A Groq Qwen3 agent runs a ReAct loop (Reason → Act → Observe → Repeat). It looks at the attack surface, decides what to test, executes the attack using real HTTP probes, observes the result, and repeats — autonomously, step by step. It tests for SQL injection, reflected and stored XSS, IDOR, CSRF, and missing security headers.
  • Stream — Every agent thought, every tool call, every vulnerability discovered is streamed to a live dashboard via Server-Sent Events in real time. You watch the agent think.
  • Report — When the scan completes, Groq generates a full security assessment report with CVSS severity scores, exact reproduction steps, and AI-written remediation advice for every finding.

How we built it

The stack is fully serverless and streams end-to-end.

The React + Vite frontend sends a scan request to Cloudflare Workers (Hono framework), which creates a scan record in Cloudflare D1 and triggers the agent job on Modal.

Modal spins up a Python container with Playwright and Chromium baked in. The agent runs three sequential phases: Playwright crawls the target, Gemini Flash parses the attack surface, then a Groq Qwen3 32B agent runs the ReAct attack loop using OpenAI-compatible function calling. The agent has access to five tools: probe_xss, probe_sqli, check_idor, check_stored_xss, and http_request. It calls them autonomously in sequence until it exhausts the attack surface.

Every event, thought, action, result, vulnerability, is POSTed back to Cloudflare Workers via HTTP callbacks, stored in D1, and immediately pushed to the frontend over a persistent SSE connection. The entire pipeline from URL submission to final report runs in under two minutes.

Challenges we ran into

Getting Playwright inside Modal was the first wall. Installing Chromium in a serverless container and making it run headlessly without sandbox issues required specific image configuration and build flags.

The async ReAct loop and streaming had to be carefully coordinated. The agent runs asynchronously on Modal while the frontend holds an open SSE connection to Cloudflare Workers. We had to design a callback architecture where Modal POSTs progress events to Workers in real time, which Workers immediately flush to the SSE stream, all without blocking or losing events.

Vulnerability deduplication was trickier than expected. The LLM would sometimes rediscover a vulnerability it had already found, or test the same endpoint multiple times under different framings. We had to build a deduplication layer that tracks confirmed findings by type and endpoint to avoid flooding the report with duplicate entries.

Keeping the agent on task required careful prompt engineering. Without constraints, the Qwen3 agent would either stop too early or go in circles. We set a maximum step budget and a mandatory IDOR enumeration phase that runs before the LLM loop, ensuring the highest-value checks always happen regardless of what the model decides to do.

Accomplishments that we're proud of

We built a working autonomous security agent in under 24 hours that finds real vulnerabilities. Not simulated ones, it actually bypasses authentication with SQL injection, actually accesses other users' data via IDOR, and actually injects scripts via XSS. The evidence in the report is the live HTTP response proving it.

The real-time streaming dashboard works exactly as intended. Watching the agent reason through an attack surface, decide what to probe, and then surface a critical CVSS 9.8 vulnerability in real time, that's the moment the product becomes viscerally real.

We're also proud of the architecture. Every component is serverless, stateless, and independently deployable. The entire stack runs on free tiers.

What we learned

Building an AI agent that takes real-world actions is fundamentally different from building a chatbot. The ReAct loop pattern, giving the model a set of tools and letting it reason about what to call, is powerful, but the quality of the tool schemas and the system prompt determines almost everything about the agent's behavior. We spent significant time on the attack planner's system prompt and tool descriptions.

We also learned how to build reliable streaming pipelines across multiple asynchronous services. The callback architecture between Modal and Cloudflare Workers, and from Workers to the browser over SSE, required thinking carefully about event ordering, connection lifecycle, and what happens when any piece fails mid-scan.

What's next for Phantom

  • Authenticated scanning — support for session cookies and login credentials so Phantom can test pages behind authentication
  • More vulnerability classes — SSRF, XXE, open redirect, JWT algorithm confusion, GraphQL introspection abuse
  • CI/CD integration — a GitHub Action that runs Phantom on every pull request and blocks merges if critical vulnerabilities are found
  • Differential scanning — compare two scans and surface only new vulnerabilities introduced between deploys
  • Remediation verification — re-test specific endpoints after a fix to confirm the vulnerability is closed

Built With

Share this project:

Updates