From login URL to exploited findings - autonomously.
Built by Virtue Security - We create resilient organizations through better penetration tests.
VirtueWebAgent is an autonomous web-application penetration testing agent built by the pentesters at Virtue Security. Give it a login URL, credentials, and a scope. It discovers how to authenticate, writes a repeatable login script, drives a real browser through complex SPAs and business-logic flows, maps every REST/GraphQL endpoint and SPA route, then hunts and exploits vulnerabilities including cross-tenant and role-based authorization controls, business-logic flaws, XSS, XXE, RCE, SSRF, Path Traversal, and SQLi.
It hands you two reports — one of findings it confirmed by exploiting them, and one of leads worth a human's manual investigation — each as an interactive HTML dashboard plus Markdown, backed by a reconciliation audit that catches anything that didn't make it in. You can mark findings as false positives and have that stick across regenerations.
For authorized security testing only. You are responsible for defining the scope and using it only on authorized pentests. Apply to Anthropic's Cyber Verification Program before starting - approval is not immediate.
Check out the Gallery to see examples!
flowchart LR
A["🔐 Phase 1\nLogin Discovery"] --> B["🕷️ Phase 2\nApp Crawl"]
B --> C["⚡ Phase 3\nExploit"]
C --> D["📋 Reports\nConfirmed + Leads"]
style A fill:#1a0810,stroke:#e8334a,color:#f07070
style B fill:#081018,stroke:#00d4ff,color:#70d8ff
style C fill:#081810,stroke:#00e87a,color:#70f0a0
style D fill:#100a18,stroke:#a855f7,color:#c084fc
| 🔐 | Phase 1 - Login Discovery | Explores the login flow, handles MFA and SSO, writes a deterministic auto_login.py Playwright script that re-authenticates on demand |
| 🕷 | Phase 2 - Application Crawl | Drives a real browser as each authenticated role; maps REST endpoints, GraphQL, SPA routes, WebSockets, and business-logic flows |
| ⚡ | Phase 3 - Exploit & Report | Analyzes JavaScript + captured traffic for vulnerabilities, pauses for human exploit approval, attacks confirmed candidates, produces two HTML+Markdown reports, a reconciliation audit, and supports persistent false-positive triage |
Inputs: Login URL · Account Credentials · In-Scope and Out-of-Scope URL Prefixes
|
🔐 Authentication JWT Forgery · Broken Authentication Flows · MFA Bypass · OAuth Misconfiguration · Session Fixation · Credential Exposure in JS |
🛡️ Authorization Cross-Tenant Isolation · Role-Based Authorization · IDOR · Privilege Escalation · Forced Browsing · SPA Route Guard Bypass · Mass Assignment |
|
💉 Injection & Client-Side Attacks SQL Injection · Stored / Reflected / DOM XSS · SSRF (OOB via interactsh) · XXE · RCE · Path Traversal · Open Redirect · PostMessage Origin Bypass |
⚙️ Business Logic Price & Quantity Manipulation · Workflow Violations · Hidden Parameter Abuse · Client-Side Validation Bypass |
|
🌐 API, Protocol & Feature Coverage SPA Routes · REST · GraphQL · WebSocket · SOAP · Feature Flags · Service Workers · Client-Side Storage |
🔍 Reconnaissance Hardcoded Secrets in JavaScript · Exposed Debug Endpoints · JavaScript Libraries and Framework Vulnerabilities · SPA Route Discovery · REST API Discovery |
- Accepted into the Cyber Verification Program - required for Claude to perform security testing tasks without real-time blocks. Apply before starting; approval is not immediate.
- Claude Code must already be installed and logged in on the host - the container mounts
~/.claudefrom the host - Docker Engine (or Docker Desktop on macOS/Windows)
- Tested on Ubuntu 25.10 and 26.04 hosts (VM preferable for extra isolation); likely works on most Debian/Ubuntu-based distributions
- Clone this repository
cd dockercp .env.example .envand edit.envand set UID and GID to matchid -uandid -gdocker compose build(first build downloads Go, Chrome, and Node tools - allow 15–20 minutes)
Always run this tool in a VM to further isolate Claude Code.
- Start the container:
docker compose up -d - Check the logs:
docker compose logs - Open the virtual desktop in your browser: http://localhost:6080/vnc.html and click "Connect"
- Open a shell:
docker compose exec apppentest bash - Start a tmux session:
tmux new -s main- Always work inside tmux. If your terminal disconnects or you close the window, your session keeps running. Re-enter the container with
docker compose exec apppentest bash, then reattach withtmux attach -t main. - Create new terminal tabs with Ctrl+B then C.
- Switch between tabs with Ctrl+B N or P for next and previous.
- Scroll the terminal text with Ctrl+B plus the page up and page down keys
- Always work inside tmux. If your terminal disconnects or you close the window, your session keeps running. Re-enter the container with
The virtual environment is created automatically when the container first starts. Activate it at the start of each shell session:
source scripts/.venv/bin/activatedocker compose down
There is a setup step, three pipeline phases, and then a review and validate step:
- VirtueWebAgent
- Install and Launching the Docker Container
- Web Application Pentesting Pipeline and Usage
- FAQs
- Gallery
- Open the existing template: project.json
- Replace the example URL with your application's actual login page URL:
"login": {"url": "https://www.example.com", - In "login" ➤ "users" ➤ "credentials":
- Add one or more users
- Set their username, password, tenant, TOTP secret, etc. Fields are free-form - use descriptive names like
username,password, andtotp_secretand the agent will infer them. - For email-based OTP, the agent expects an
emails.ndjsonfile in the root of this folder containing the content of the email. You would need to write a script to pull emails down and load them into that file.
- In "crawl" ➤ "in_scope_prefixes" and "out_of_scope_prefixes"
- Fill in the whitelist for in-scope prefixes
- Fill in any exceptions to the above whitelist in out-of-scope prefixes
- Each entry is a host or URL prefix. In addition to literal prefixes (e.g.
https://www.example.com/), entries support host wildcards (*.example.com). Those host wildcards do not match the parent domain, so specify both*.example.comandexample.comif you want the parent domain and all subdomains. The scheme (https://orhttp://) and port are optional. An out-of-scope match always wins over in-scope.
The remaining fields will be filled in by the agent during Phase 1.
interactsh-client is pre-installed and is one of the two persistent capture services the orchestrator starts automatically and keeps running across all phases. By default it connects to public Interact.sh OAST servers (oast.pro, oast.live, etc.) - no configuration is needed for most engagements. The agent uses it during Phase 3 for SSRF detection and, where applicable, MFA OTP capture via email.
For engagements requiring a private interactsh server (air-gapped networks, compliance requirements, or to avoid sending interaction data to public infrastructure):
1. Deploy the server on a host with a public IP and a wildcard DNS record pointing to it:
interactsh-server -domain <your-domain> -ip <your-server-ip>The server prints an authentication token on startup - save it.
2. Set oob.server and oob.token in project.json before running Phase 1:
"oob": {
"server": "https://<your-domain>",
"token": "<your-token>"
}The pipeline reads these values at Phase 1 startup and passes them to interactsh-client. The remaining oob fields (domain, log_path, pid) are populated automatically when Phase 1 runs.
Note: The public OAST servers do not support FTP, LDAP, or SMB interaction capture. Those protocols require a self-hosted
interactsh-server.
- Start Claude Code:
claude --dangerously-skip-permissions(Always run this in the Docker container inside an isolated VM) (Only use--dangerously-skip-permissionsinside the isolated container.)/VirtueWebAgent-Phase1 dry-run- Choose
/VirtueWebAgent-Phase1or/VirtueWebAgent-Phase1 use up to 2 sub-agents at oncebased on your subscription level - At startup the orchestrator automatically starts the capture proxy and interactsh (see above). It then discovers the login flow, builds
scripts/auto_login.py, and verifies it can log in every configured user. - If the run is interrupted, re-run the same command - the orchestrator resumes from its saved state automatically.
- Review the results:
- Review project.json values (the agent populates session cookies/headers)
- Review findings/phase1/login-instructions.md
- Optional manual re-verification:
python3 scripts/auto_login.py --verify-all-credentials
- Do not stop the proxy or interactsh — they stay running for Phase 2. The orchestrator prints a reminder at the end of the phase.
- Start Claude Code:
claude --dangerously-skip-permissions(Always run this in the Docker container inside an isolated VM)/VirtueWebAgent-Phase2 dry-run- Choose
/VirtueWebAgent-Phase2or/VirtueWebAgent-Phase2 use up to 2 sub-agents at oncebased on your subscription level - At startup the orchestrator confirms the proxy and interactsh are still running (and starts them if not). It then runs, automatically and in order: JavaScript collection as the logged-in user (
collect-javascript), the prerequisite scanners (run-betterleaks,run-retirejs), the mechanical pre-crawls that seed the interactive crawl (deterministic-crawl,katana-crawl), the authenticated crawl for every role, and a late authenticatednuclei-dastscan. None of these are manual any more. - If the run is interrupted, re-run the same command - the orchestrator resumes from its saved state automatically.
- Review the Crawl and Network Call Coverage Report: findings/phase2/report.html
- Do not stop the proxy or interactsh — they stay running for Phase 3. The orchestrator prints a reminder at the end of the phase.
- (Optional) Filter the consolidated proxy traffic for a Burp DAST scan (Burp itself is still driven manually):
python3 scripts/filter_mitm_for_dast_scan.py "findings/mitmdump/*.ndjson" --output findings/mitmdump/dast_filtered.ndjson --limit 3- Install the Burp plugin: https://github.com/VirtueSecurity/VirtueBurpAIPipelineTools - it reads session cookies from
project.jsonso the scanner stays authenticated - Open Burp ➤ Settings ➤ Extensions ➤ Virtue AI Pipeline Tools ➤
- AI Session Handler: Full Path to project.json - copy/paste the absolute path
- AI Session Handler: Enabled & Apply to the Global and Scanner - check mark (remove when done scanning)
- Set up an authenticated session by running
python3 scripts/auto_login.py --stay-logged-in 1to populate headers and cookies inproject.json - Import the filtered, de-duplicated list of crawl URLs to scan by going to SmartScan ➤ Scan Setup Tab ➤ Import Filtered NDJSON Traffic and choose
findings/mitmdump/dast_filtered.ndjson. This will import the items into organizer. Review the items there, choose the items you want to scan and then start the scan. - Review the findings and consider exporting select findings into the
findings/directory and referencing them in Phase 3
- Start Claude Code:
claude --dangerously-skip-permissions(Always run this in the Docker container inside an isolated VM)/VirtueWebAgent-Phase3 dry-run- Choose
/VirtueWebAgent-Phase3or/VirtueWebAgent-Phase3 use up to 2 sub-agents at oncebased on your subscription level - At startup the orchestrator confirms the proxy and interactsh are still running (and starts them if not).
- If the run is interrupted, re-run the same command - the orchestrator resumes from its saved state automatically.
- Before exploitation, the agent pauses and writes
findings/phase3/exploit-review.json. Open the file and review each entry. For any finding you do not want exploited, set"skip": true. Pay particular attention to entries wheredata_mutation_riskishighormedium, or whererequires_second_sessionistrue- these can affect real data or other user accounts. Save the file, then replycontinuein the Claude session. - When the phase finishes, stop the persistent services — this is the point at which you shut them down (the orchestrator also prints this reminder at the end of the phase):
python3 scripts/proxy.py stop python3 scripts/interactsh.py stop # saves the interactsh session file
- Start at the document index: findings/index.html — a rich, clickable navigation hub for every artifact the pipeline produced, organized both by phase/task and by use case. Human-facing reports are emphasized; machine/agent data files are catalogued too, each with a short summary. A plain-Markdown mirror is at findings/index.md.
- Review the headline reports. Each comes as a self-contained HTML dashboard and a Markdown projection:
- Agent-exploited issues (you still need to carefully verify and re-rate risk): findings/phase3/report-confirmed.html / .md
- Issues worth manual investigation: findings/phase3/report-manual-validation.html / .md
- Check nothing was dropped: the reconciliation audit findings/phase3/report-omissions.md lists any finding that did not reach a report (and why) — unclassified findings, parse errors, missing evidence, prose-only dynamic findings, etc.
- Mark false positives (persists across regeneration): to set a finding aside, either ask the agent ("mark
rest-001as a false positive because …"), runscripts/.venv/bin/python scripts/mark_false_positive.py --id <id> --reason "<reason>", or editfindings/phase3/false-positives.jsondirectly. Other statuses:--status duplicate --duplicate-of <id>,--status accepted_risk,--status confirmed_override. Then re-run the report tasks. False positives are never deleted or renumbered — they stay in the table in place, struck-through with a badge, excluded from the counts, and hide-able via the report's All / Hide triaged / Only triaged filter. The overlay is user-owned; the pipeline only reads it.
The knowledge directory contains information and techniques the agent has learned through trial and error. Run the following commands before archiving each project:
/VirtueWebAgent-kb-harvest/VirtueWebAgent-kb-consolidatecp -r knowledge/ /path/to/shared/knowledge/to carry discoveries forward. Copy these back into future projects.
Run /VirtueWebAgent-review-execution-notes to have the agent summarize the problems it encountered and suggest solutions to fix them in the future.
Run /VirtueWebAgent-ExplainPhase <phase-number> to have Claude Code explain the steps and tasks of a given phase (1, 2, or 3).
Yes; however, you will need to provide additional instructions to the orchestrator to limit the number of parallel subagents to avoid exhausting your session limits. Use the following additional instructions: allow nested agents as deep as necessary but otherwise limit sub-agents to 1 sub-agent at once. For example, you would use the Phase 3 command with this additional instruction as follows: /VirtueWebAgent-Phase3 allow nested agents as deep as necessary but otherwise limit sub-agents to 1 sub-agent at once
Claude does not have training data reflecting the vulnerabilities present in the targeted vulnerable applications below, reducing the chance it will simply look up the vulnerabilties instead of finding them itself:
Copyright 2026 Virtue Security. Licensed under the Apache License, Version 2.0 (docs/LICENSE.txt).







