Back to Articles

bbscope: Building a Multi-Platform Bug Bounty Scope Aggregator with PostgreSQL and LLM Normalization

[ View on GitHub ]

bbscope: Building a Multi-Platform Bug Bounty Scope Aggregator with PostgreSQL and LLM Normalization

Hook

Bug bounty hunters who monitor hundreds of programs lose opportunities every day because scope changes are buried across five different platforms with inconsistent APIs and no unified notification system.

Context

The bug bounty ecosystem is fragmented. A serious hunter might track programs across HackerOne, Bugcrowd, Intigriti, YesWeHack, and Immunefi simultaneously. Each platform has its own web interface, its own API structure, and its own way of representing scope. When a company adds a new subdomain to their scope or expands to a new IP range, it appears as a quiet update on a single platform’s UI. Competitive hunters need to catch these changes within hours, not days.

Traditional approaches involve manual checking, brittle custom scripts for individual platforms, or relying on third-party aggregators that may not include private programs you’re invited to. bbscope solves this by providing a unified CLI tool written in Go that polls all five major platforms, stores everything in PostgreSQL for historical comparison, and even includes experimental LLM integration to clean up the notoriously messy scope strings that programs provide. It’s infrastructure for scope monitoring, not just a one-time export tool.

Technical Insight

Processing

Platforms

Clean scope data

Raw scope data

Diff detection

additions/removals

Query filters

Text/JSON/CSV

CLI Entry Point

Poll Command

DB Command

HackerOne API

Bugcrowd API

Intigriti API

YesWeHack API

Immunefi API

Auth Handler

Tokens/TOTP/Cookies

Rate Limiter

Concurrent Requests

AI Normalizer

GPT-4o-mini

PostgreSQL

Scope History

System architecture — auto-generated

bbscope’s architecture follows a clear separation between data ingestion (poll) and data querying (db). The polling system handles five different platform APIs with dramatically different authentication schemes—HackerOne uses API tokens, Bugcrowd requires 2FA secrets for TOTP generation, Intigriti uses bearer tokens, and YesWeHack supports both session cookies and credential-based auth. Each platform connector implements concurrent HTTP requests with rate limiting to avoid triggering anti-abuse mechanisms.

The database schema tracks scope changes over time by storing each poll result with timestamps. When you run a new poll with the --db flag, bbscope compares the fresh targets against the previous poll’s data and identifies additions and removals. This is the killer feature for competitive hunters—you get instant visibility into scope expansions without manually diffing program pages.

Here’s how you’d set up centralized polling for all platforms with change tracking:

# Initial poll stores baseline
bbscope poll --db

# Later polls detect changes
bbscope poll --db
# Output shows:
# [+] New targets: api.example.com, *.staging.example.com
# [-] Removed: legacy.example.com

The AI normalization layer is where things get interesting. Bug bounty programs often provide scope in wildly inconsistent formats: some use clean DNS wildcards, others paste entire paragraphs with embedded exclusions. bbscope can batch-process these through OpenAI’s gpt-4o-mini (or compatible providers) to extract structured targets and even flag out-of-scope entries based on natural language descriptions:

# ~/.bbscope.yaml AI configuration
ai:
  provider: "openai"
  api_key: "sk-..."
  model: "gpt-4o-mini"
  max_batch: 25        # Process 25 targets per API call
  max_concurrency: 10  # Run 10 concurrent batches

When you poll with the --ai flag, bbscope sends raw scope strings to the model with a system prompt that instructs it to extract clean URLs, wildcards, and CIDR ranges while discarding noise. The max_batch setting is crucial—batching reduces API calls (and costs) significantly compared to processing targets individually.

The querying interface provides smart filtering by target type. Instead of manually parsing scope strings to find all wildcard domains or CIDR blocks, you can use:

# Get all wildcard domains from HackerOne programs
bbscope db get --platform h1 --category wildcards

# Export mobile app identifiers as JSON
bbscope db get --category mobile --output json

# Get all URLs from a specific program
bbscope db get --program "Example Corp" --category urls --output csv

The category extraction happens through pattern matching—bbscope identifies URLs via protocol prefixes, wildcards via asterisk notation, CIDRs via slash notation, and mobile apps via platform-specific bundle identifiers. This categorization is what enables targeted reconnaissance workflows where you pipe different scope types into different tools (wildcards to subdomain enumeration, CIDRs to network scanning, etc.).

Docker deployment is first-class. The project publishes images to GitHub Container Registry automatically, and you can run the entire stack with volume-mounted configuration:

# Pull latest image
docker pull ghcr.io/sw33tlie/bbscope:latest

# Run with mounted config and DB polling
docker run --rm \
  -v ~/.bbscope.yaml:/root/.bbscope.yaml \
  ghcr.io/sw33tlie/bbscope:latest poll --db

For teams running shared infrastructure, you’d typically combine this with a cron job and a centralized PostgreSQL instance, creating a continuously-updated scope database that multiple hunters can query concurrently. The companion website at bbscope.com provides an hourly-updated list of public scopes from all supported platforms.

Gotcha

The credential management story is messy. You’re storing plaintext API tokens and potentially 2FA TOTP secrets in ~/.bbscope.yaml. For platforms like Bugcrowd and YesWeHack, you need to extract your TOTP secret (the base32 string that your authenticator app uses) and paste it into the config. This works, but it’s a security footgun—if that file leaks, someone has full access to your bug bounty accounts. There’s no support for credential managers or encrypted storage, so you’re responsible for file permissions and secure handling.

The AI normalization is explicitly marked as experimental, and for good reason. LLMs are non-deterministic and can hallucinate or omit entries. If you’re using --ai for automated polling, you might silently lose scope targets if the model decides they’re not relevant or fails to parse them correctly. The batch processing approach helps with cost but means failures affect multiple targets at once. You also need a paid OpenAI API key (or compatible provider), which adds operational cost that scales with the number of programs you monitor. For critical scope tracking, you’d want to keep the raw, uncleaned data and treat LLM output as a convenience layer, not ground truth.

PostgreSQL is mandatory for the most valuable features—change tracking, historical queries, and scope categorization all require the database. If you just want a quick scope export without infrastructure overhead, you’re stuck with the raw poll output that lacks persistence. The Docker setup helps, but you’re still managing database backups and potential maintenance as the tool evolves. For casual users who check scope monthly, this is overkill. The tool assumes you’re running continuous monitoring, not ad-hoc queries.

Verdict

Use bbscope if you’re a full-time bug bounty hunter managing invitations across multiple platforms and need automated change detection to catch new scope within hours of publication. The PostgreSQL integration and category-based querying turn scope monitoring from a manual chore into a queryable database, and the change tracking alone justifies the setup cost if you’re competitive in time-sensitive programs. Also use it if you’re building team infrastructure—the Docker deployment and concurrent access patterns make it suitable for shared scope databases. Skip it if you only actively hunt on one or two platforms, don’t want to manage a PostgreSQL instance, or prefer stateless tools that work without persistent infrastructure. The credential storage requirements make it unsuitable for environments with strict security policies. Also skip if you’re uncomfortable with experimental AI features that might omit scope entries—stick to manual verification in that case. For casual hunters who check scope monthly, the operational overhead outweighs the benefits.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/sw33tlie-bbscope.svg)](https://starlog.is/api/badge-click/cybersecurity/sw33tlie-bbscope)