Documentation
Developer docs.
Everything you need to install, configure, and integrate BrokenApp into your workflow. CLI reference, IDOR scanning, auth matrix, exposure scanning, baseline & triage, auth flow testing, GitHub integration, GraphQL, business logic testing, export, CI/CD, and MCP server.
Getting started
Install and run your first scan.
Installation
$ # Install via cargo (Rust toolchain required)
$ cargo install brokenapp
$ # Or download the binary
$ curl -sSL https://brokenapp.io/install.sh | sh
Quick start
$ brokenapp scan --url https://yourapp.com
# Crawls all routes, tests endpoints, generates report
# Output: ./scan-results/spec.json, bugs.json, report.md
No configuration file required. No signup. No auth. Point it at any publicly accessible URL and it runs a full crawl.
System requirements
- Chromium-based browser (auto-downloaded on first run)
- macOS, Linux, or Windows (WSL2)
- 2GB RAM minimum, 4GB recommended for large sites
- Rust 1.75+ (if building from source)
CLI reference
All commands at a glance.
brokenapp scan
Full scan of a deployed web application. Crawls routes, tests endpoints, captures network traffic, generates structured reports.
| Flag | Type | Default | Description |
|---|---|---|---|
| --url | string | — | Target URL (required) |
| --mode | string | full | Scan mode: full, security, performance |
| --depth | number | 5 | Max crawl depth into route tree |
| --config | path | — | Config TOML with auth + scan options |
| --output | path | ./scan-* | Output directory |
| --headless | bool | true | Run browser in headless mode |
brokenapp diff
Compare two scan results. Shows resolved issues, still-open issues, and newly introduced issues.
| Flag | Type | Default | Description |
|---|---|---|---|
| <scan-a> | path | — | First scan directory (before) |
| <scan-b> | path | — | Second scan directory (after) |
| --format | string | text | Output format: text, json, md |
brokenapp idor-scan
NewAutomated IDOR/BOLA detection. Replays requests from one user session using another user's credentials to detect broken authorization.
| Flag | Type | Default | Description |
|---|---|---|---|
| --scan-a | path | — | Scan output dir for User A (required) |
| --scan-b | path | — | Scan output dir for User B (required) |
| --config-b | path | — | Config TOML with User B's auth (required) |
| --output | path | ./idor-scan-* | Output directory |
| --limit | number | — | Max endpoints to test |
| --max-ids | number | 3 | Max ID variations per endpoint |
| --timeout | seconds | 30 | Per-request timeout |
| --delay-ms | ms | 100 | Delay between requests |
| --include-delete | bool | false | Include DELETE endpoints (destructive) |
| --path-filter | regex | — | Filter endpoint paths by regex |
| --ignore-https-errors | bool | false | Skip TLS certificate verification |
brokenapp auth-matrix
NewMulti-role authorization matrix. Define N roles in a roles.toml file, scan each, then test every N×(N-1) pair for broken access control.
| Flag | Type | Default | Description |
|---|---|---|---|
| --roles | path | roles.toml | TOML file defining roles and their auth configs |
| --scan-dir | path | — | Base directory containing per-role scan outputs |
| --mode | string | replay | Mode: full (scan + replay) or replay (existing scans) |
| --url | string | — | Target URL (required in full mode) |
| --output | path | ./auth-matrix-* | Output directory |
| --concurrency | number | 4 | Parallel pair tests |
| --fail-on | string | — | Exit 1 if severity >= threshold (critical, high, medium) |
brokenapp exposure-scan
NewExposure and secrets scanning. Passive analysis of captured traffic plus active probing of sensitive paths for leaked credentials, API keys, and debug endpoints.
| Flag | Type | Default | Description |
|---|---|---|---|
| --scan-dir | path | — | Scan output directory to analyze (required) |
| --active | bool | false | Enable active probing of sensitive paths |
| --url | string | — | Target URL for active probing (from scan if omitted) |
| --output | path | ./exposure-* | Output directory |
| --severity | string | low | Minimum severity to report: critical, high, medium, low |
| --config | path | — | Config TOML with auth for authenticated probing |
brokenapp baseline
NewBaseline and triage management. Subcommands: create, apply, diff.
| Flag | Type | Default | Description |
|---|---|---|---|
| create --scan | path | — | Create baseline from scan directory |
| apply --scan | path | — | Scan directory to filter |
| apply --baseline | path | — | Baseline JSON to apply |
| diff <a> <b> | path | — | Compare two scan directories |
| --status | string | accepted | Default triage status: accepted, triaged, false_positive |
| --output | path | — | Output directory for filtered results |
brokenapp auth-test
NewAuth flow testing. Supports Supabase, Firebase, cookie, bearer, and form-based auth.
| Flag | Type | Default | Description |
|---|---|---|---|
| --config | path | — | Config TOML with auth provider settings (required) |
| --output | path | ./auth-results | Output directory |
| --tests | string | — | Specific tests: login-success, login-failure, session-persistence, token-refresh, logout-invalidation |
brokenapp github
NewGitHub integration. Subcommands: sync, comment-pr, sarif.
| Flag | Type | Default | Description |
|---|---|---|---|
| sync --repo | string | — | GitHub repo (owner/name) |
| sync --scan | path | — | Scan directory |
| sync --token | string | — | GitHub token ($GITHUB_TOKEN) |
| sync --baseline | path | — | Baseline to exclude triaged findings |
| sync --dry-run | bool | false | Preview without creating issues |
| comment-pr --pr | number | — | PR number to comment on |
| sarif --output | path | results.sarif | SARIF output file |
brokenapp logic-test
NewBusiness logic testing. Step-skip detection and replay attack detection.
| Flag | Type | Default | Description |
|---|---|---|---|
| --scan | path | — | Scan output directory (required) |
| --config | path | — | Config TOML with auth (required for replay) |
| --output | path | ./logic-results | Output directory |
| --tests | string | — | Specific tests: step-skip, replay |
brokenapp export
NewConsolidated report export. Merges all scan artifacts into a single PDF, Markdown, or CSV report.
| Flag | Type | Default | Description |
|---|---|---|---|
| --scan-dir | path | ./scan-results | Scan output directory containing JSON artifacts |
| --format | string | — | Output format: pdf, md, csv (required) |
| --output | path | ./report | Output directory for generated report |
| --title | string | — | Custom report title (defaults to target URL) |
| --severity | string | low | Minimum severity: info, low, medium, high, critical |
| --branded | bool | false | Include BrokenApp branding in header/footer |
| --include | string[] | — | Sections to include (comma-separated): header, summary, findings, idor, auth-matrix, exposure, endpoints, footer |
| --exclude | string[] | — | Sections to exclude (comma-separated) |
IDOR / BOLA scanning
How cross-user authorization testing works.
IDOR (Insecure Direct Object Reference), also known as BOLA (Broken Object Level Authorization), is the #1 vulnerability class by volume and payout in bug bounty programs. BrokenApp automates detection in 7 phases.
The workflow
# Step 1: Scan as admin user
$ brokenapp scan --url https://app.com --config admin.toml --output ./admin-scan
# Step 2: Scan as viewer user
$ brokenapp scan --url https://app.com --config viewer.toml --output ./viewer-scan
# Step 3: Run IDOR scan (replays admin requests with viewer creds)
$ brokenapp idor-scan --scan-a ./admin-scan --scan-b ./viewer-scan --config-b viewer.toml
7-phase pipeline
Severity classification
Critical
Write endpoints (POST/PUT/PATCH/DELETE) with confirmed unauthorized access
High
Read endpoints (GET) with confirmed access to another user's data
Medium
Likely but not conclusively confirmed (2xx response, different body)
Low
Edge cases and inconclusive results requiring manual review
Multi-role auth matrix
N×(N-1) authorization testing across every role pair.
Define every role in your application. BrokenApp scans each role independently, then replays every role's requests using every other role's credentials. The result is a compliance heatmap showing exactly where access control breaks down.
Validation
The roles.toml file requires at least 2 roles with unique names. In full mode, each role is scanned sequentially before pair testing begins. In replay mode, existing scan directories must match role names exactly.
Define roles
# roles.toml
[[roles]]
name = "admin"
auth.type = "bearer"
auth.token = "eyJhbGci...admin"
[[roles]]
name = "editor"
auth.type = "bearer"
auth.token = "eyJhbGci...editor"
[[roles]]
name = "viewer"
auth.type = "cookie"
auth.name = "session"
auth.value = "abc123..."
[[roles]]
name = "anon"
# No auth block — tests unauthenticated access
Two modes
Full mode
Runs a fresh scan for every role, then tests all N×(N-1) pairs. Use when starting from scratch.
$ brokenapp auth-matrix
--mode full
--url https://app.com
--roles roles.toml
Replay mode
Uses existing scan outputs. Faster when you've already scanned each role individually.
$ brokenapp auth-matrix
--mode replay
--scan-dir ./scans
--roles roles.toml
Compliance heatmap
The output is an N×N matrix where each cell shows how many endpoints from the row-role were accessible using the column-role's credentials.
| Owner ↓ / Creds → | admin | editor | viewer | anon |
|---|---|---|---|---|
| admin | — | 4 | 7 | 2 |
| editor | 0 | — | 3 | 1 |
| viewer | 0 | 0 | — | 0 |
Each number = endpoints from the row-role that were accessible with the column-role's credentials. 0 = no IDOR. N = N confirmed IDORs.
Output files
auth-matrix.json
Full matrix data with per-pair IDOR findings, verdicts, and severity.
heatmap.md
Markdown heatmap table for embedding in reports or PRs.
pairs/admin→viewer.json
Per-pair detail files with individual endpoint verdicts and evidence.
summary.md
Human-readable summary with total findings by severity.
Exposure & secrets scanning
Find leaked credentials, keys, and debug endpoints.
BrokenApp scans for exposed secrets and sensitive data using two complementary approaches: passive analysis of captured network traffic, and active probing of known sensitive paths. Passive scanning runs automatically on every brokenapp scan — no extra commands needed. Use brokenapp exposure-scan for standalone analysis or to enable active probing.
Auto-integration
Every brokenapp scan automatically runs passive exposure analysis and writes exposure-report.json + exposure-report.md to the scan output directory. No configuration required.
The workflow
# Run after a standard scan — analyzes captured traffic
$ brokenapp exposure-scan --scan-dir ./admin-scan
# Add --active to probe sensitive paths
$ brokenapp exposure-scan --scan-dir ./admin-scan --active
CRITICAL /.env exposed — AWS key AKIA****7X2Q
HIGH Stripe key in /api/config response
HIGH /debug/pprof accessible without auth
MEDIUM Source map /assets/app.js.map exposed
Two scanning modes
Passive mode
Analyzes network.jsonl from an existing scan. No additional requests sent. Scans response bodies and headers for secret patterns.
- •API keys (AWS, GCP, Stripe, GitHub, Twilio, SendGrid)
- •Database connection strings (Postgres, MySQL, MongoDB)
- •JWT tokens in query params or response bodies
- •Server version disclosure headers
- •Verbose errors with SQL/stack trace indicators
- •Slack tokens and webhook URLs
- •Internal IP address leakage
Active mode
Probes known sensitive paths against the target. Sends real requests to check for exposed files and endpoints.
- •/.env, /.env.local, /.env.production
- •/.git/config, /.git/HEAD
- •/debug/pprof, /debug/vars, /actuator
- •/server-status, /server-info
- •/*.js.map (auto-discovered from traffic)
- •/graphql (introspection enabled)
- •/phpinfo.php, /phpmyadmin, /wp-admin
- •/api/docs, /swagger.json, /openapi.json
Secret pattern library
18 compiled regex patterns with severity, CWE mapping, and remediation metadata. All secrets are automatically masked in output (e.g. AKIA****7X2Q).
AWS access keys
AKIA[0-9A-Z]{16}
GCP API keys
AIza[0-9A-Za-z_-]{35}
GitHub tokens
ghp_|gho_|ghs_|github_pat_
Stripe keys
sk_live_|rk_live_
Slack tokens
xoxb-|xoxp-|xoxa-|xoxr-
Slack webhooks
hooks.slack.com/services/
SendGrid
SG\.[a-zA-Z0-9_-]{22}
Twilio
SK[a-f0-9]{32}
Mailgun
key-[a-zA-Z0-9]{32}
Firebase
AAAA[a-zA-Z0-9_-]{7}:
Heroku API
[a-f0-9]{8}-...-[a-f0-9]{12}
Private keys
-----BEGIN.*KEY-----
Database URLs
postgres|mysql|mongodb://…@
JWT in params
eyJ[a-zA-Z0-9_-]*\.
Internal IPs
10\.|172\.1[6-9]|192\.168
Generic secrets
secret|password|token=…
Server headers
X-Powered-By, Server
Verbose errors
SQL|stacktrace|Traceback
Severity classification
Critical
Active credentials exposed: AWS keys, database passwords, API tokens with write access.
High
Sensitive files accessible: .env, .git/config, debug endpoints, admin panels.
Medium
Information disclosure: source maps, server version headers, verbose errors.
Low
Minor leaks: internal IPs in headers, technology fingerprinting.
Output files
exposure-report.json
All findings with severity, evidence, CWE mapping, and masked secrets.
exposure-report.md
Human-readable report with findings grouped by severity.
secrets.json
Extracted secrets with type, location, and masked value.
probes.json
Active probe results with status codes and response data.
Baseline & triage
Stop re-triaging the same findings.
Create a baseline from any scan. Fingerprint each finding using Blake3 hashing. Mark findings as accepted risk, false positive, or triaged. Subsequent scans filter out known issues — only new findings surface.
Fingerprinting strategy
Bug
category + key_fields + location.view + location.url
Exposure
category + url
IDOR
endpoint + method
All fingerprints are Blake3 hashes truncated to 32 hex characters. Same finding = same ID across scans.
Triage statuses
accepted
Known risk — accepted by the team. Will be suppressed in future scans.
triaged
Acknowledged and being worked on. Still tracked but suppressed from new-only reports.
false_positive
Not a real finding. Permanently excluded from future reports.
Auth flow testing
Supabase. Firebase. Cookie. Bearer. Form.
Native auth flow testing for modern stacks. Configure your auth provider in TOML, run one command, and BrokenApp tests login, session persistence, token refresh, and logout invalidation automatically.
Supported providers
Supabase
POST {project_url}/auth/v1/token?grant_type=password
Config: project_url, anon_key, email, password
Firebase
POST identitytoolkit.googleapis.com/v1/accounts:signInWithPassword
Config: api_key, email, password
Cookie
Set-Cookie header from login
Config: name, value
Bearer
Authorization: Bearer header
Config: token
Test cases
GitHub integration
Sync findings to issues, PRs, and Code Scanning.
BrokenApp integrates with GitHub using the REST API (no new dependencies — uses reqwest). Findings are matched to issues using fingerprint markers embedded in issue bodies.
Issue sync algorithm
SARIF export
Standard SARIF 2.1.0 format compatible with GitHub Code Scanning. Maps Bug, Exposure, and IDOR findings to SARIF result entries with ruleId, level, message, and locations. CWE and OWASP metadata included as rule properties.
GraphQL support
Per-operation endpoint detection.
BrokenApp detects GraphQL requests and splits them into individual operations. Instead of one opaque POST /graphql endpoint, your spec.json shows POST /graphql#QUERY users and POST /graphql#MUTATION createUser. This means IDOR detection, exposure scanning, and business logic testing all work on GraphQL apps.
How it works
Business logic testing
Step-skip detection and replay attack detection.
Automated detection of the two most common business logic flaws. Uses view transitions and mutation data from your scan — no manual test case configuration required.
Step-skip detection
Replay attack detection
Report export
PDF, Markdown, and CSV reports.
Consolidates all scan artifacts (bugs.json, idor-report.json, exposure-report.json, auth-matrix-report.json, security-report.json, spec.json, mutations.json) into a single unified report. Each finding gets a deterministic ID (BA-001, BA-002, etc.) via Blake3 fingerprinting. Filter by severity, include/exclude sections, and choose your output format.
Example usage
# Full PDF report with branding
$ brokenapp export --scan-dir ./scan-results --format pdf --branded
# Markdown for GitHub/HackerOne — high+ severity only
$ brokenapp export --scan-dir ./scan-results --format md --severity high
# CSV for Jira/Linear import — just IDOR and exposure findings
$ brokenapp export --scan-dir ./scan-results --format csv --include idor,exposure
Formats
Executive-ready. Rendered via headless Chrome with inline CSS. Cover page, TOC, severity chart, finding cards with evidence. A4 format. Branded header/footer when --branded is set.
Markdown
GitHub-flavored with YAML frontmatter (title, date, tool, target, finding counts). Drop into a PR, GitHub issue, or HackerOne report. Pipe tables for IDOR and auth matrix data.
CSV
One row per finding. Columns: ID, Source, Severity, Category, Title, Description, Location, CWE, OWASP, Evidence. UTF-8 with BOM for Excel/Sheets compatibility.
Report sections
Each section is included automatically when relevant data exists. Use --include or --exclude to control which sections appear.
Note: PDF export requires Chrome or Chromium installed. If unavailable, use --format md as an alternative. Finding IDs are deterministic — the same finding always gets the same BA-XXX ID across exports.
Configuration
Auth, scan options, and config files.
BrokenApp uses TOML config files for authentication and advanced scan options. Config is optional for unauthenticated scans.
Cookie auth
# config.toml
[auth]
type = "cookie"
name = "session_id"
value = "abc123..."
Bearer token auth
# config.toml
[auth]
type = "bearer"
token = "eyJhbGci..."
Form-based auth
# config.toml
[auth]
type = "form"
login_url = "https://app.com/login"
username_field = "email"
username = "[email protected]"
password_field = "password"
password = "supersecret"
Supabase auth
# config.toml
[auth]
type = "supabase"
project_url = "https://xyz.supabase.co"
anon_key = "eyJhbGci..."
email = "[email protected]"
password = "supersecret"
Firebase auth
# config.toml
[auth]
type = "firebase"
api_key = "AIzaSy..."
email = "[email protected]"
password = "supersecret"
Scan options
# config.toml
[scan]
depth = 5
timeout = 30
headless = true
ignore_https_errors = false
exclude_paths = ["/logout", "/admin/dangerous"]
Output formats
What the scanner produces.
Every scan generates a structured output directory with multiple files covering different aspects of the scan results. Exposure reports are auto-generated with every scan.
spec.json
Complete API specification — every endpoint discovered with methods, params, and response schemas.
bugs.json
All detected issues with severity, reproduction steps, and evidence.
mutations.json
Write endpoints (POST/PUT/PATCH/DELETE) correlated with UI actions that trigger them.
security.json
Security-specific findings: headers, CORS, exposed keys, injection vectors.
network.jsonl
Full network traffic log — every request/response captured during the scan.
report.md
Human-readable Markdown report with summary, findings, and recommendations.
graph.json
Route graph and navigation tree showing how pages connect.
idor-report.json
IDOR scan findings with verdicts, severity, and body similarity scores.
auth-matrix.json
N×N matrix with per-pair IDOR counts, compliance heatmap data.
exposure-report.json
Exposed secrets, sensitive files, and debug endpoints with CWE mappings.
CI/CD integration
Scan on every push.
GitHub Actions
# .github/workflows/brokenapp.yml
name: BrokenApp Scan
on: [push]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- run: |
curl -sSL https://brokenapp.io/install.sh | sh
brokenapp scan --url ${{ env.STAGING_URL }}
brokenapp check --fail-on critical
Exit codes
0
No critical issues found
1
Critical issues detected
2
Scan failed / error
MCP server
Feed scan data to AI coding tools.
BrokenApp includes a local MCP (Model Context Protocol) server that exposes scan results to AI coding tools like Claude Code and ChatGPT Codex. The AI can read your bug report, understand the issues, and generate fixes.
Start the MCP server
$ brokenapp mcp --scan-dir ./scan-results
# MCP server running on stdio
# Tools: get_bugs, get_spec, get_endpoint, get_finding
Available tools
get_bugs
Return all bugs from the most recent scan, filterable by severity.
get_spec
Return the full API specification from the scan.
get_endpoint
Return details for a specific endpoint by method + path.
get_finding
Return detailed info for a specific bug finding by ID.
API reference
Cloud API for Pro and Team plans.
Pro, Team, and Enterprise plans include access to the BrokenApp Cloud API. Trigger scans, retrieve reports, and manage your dashboard programmatically.
Endpoints
Full API documentation with request/response schemas is available at api.brokenapp.io/docs for authenticated users. Contact sales for Enterprise API access.