Multi-protocol API security testing

Multi-protocol API security testing, self-hosted.
Burp for the non-HTTP protocols — schema-aware, Apache-2.0, Nuclei-compatible.

Bowire's discovery, recording, and replay primitives extend into vulnerability scanning. Four CLI subcommands (scan / fuzz / jwt / proxy), three template sources fed through one engine, SARIF 2.1.0 out to GitHub Code Scanning / GitLab / Azure DevOps.

Five things the incumbents miss

Every incumbent owns one transport. Bowire's sweet-spot is the intersection three other tools leave open — multi-protocol-native, schema-aware via the frame-semantics layer, recording-as-template, with the existing Nuclei templates straight on the same engine.

Multi-protocol-native

Burp Suite Pro and OWASP ZAP are HTTP-centric — gRPC needs plugins plus manual .proto wiring; SignalR, WebSocket, MQTT have at best community-contributed half-solutions. Bowire hits a gRPC service via reflection, a SignalR hub via its typed methods, an OData endpoint via $metadata, an MQTT broker via topic enumeration — each in the protocol's own dialect, not as a polyfill over HTTP.

Schema-aware

The frame-semantics framework classifies fields by kind (coordinate.latitude, image.bytes, audio.bytes, timestamp, …). The fuzzer knows not to throw SQL injection at a latitude field, knows that image.bytes deserves magic-byte mutation instead of XSS payloads, knows that audio.sample-rate is a numeric integer and not a string. No incumbent has this for non-HTTP protocols.

Recording ≡ template

Every Bowire recording carries the same shape bowire scan consumes. Add attack: true, a vulnerability metadata block, and a vulnerableWhen predicate — that is the vulnerability template format. Same replay engine the mock server uses, just with the direction flipped. Version it, review it in a PR, replay it deterministically across detector drift.

Nuclei-compatible

The 8000+ projectdiscovery/nuclei-templates set runs through the same engine. --nuclei <dir> reads the YAML templates, translates the matchers / matchers-condition / payload matrices / standard variables (, , , …) into Bowire's native AttackPredicate DSL, then runs them alongside the built-in checks and the VulnDb baseline. One engine, three template sources.

Self-hosted, Apache-2.0-licensed

No SaaS subscription, no seat counting, no data leaving your network. The 42Crunch / Salt / Bright lane is enterprise APIsec posture-management as a service — Bowire is the OSS, on-prem alternative that runs in your CI on your runners against your APIs. Free for any use including commercial.

The four security subcommands

All four ship in the same bowire binary that drives the workbench. Pipe them into CI, run them ad-hoc from a developer laptop, or call them through MCP from an AI agent — same exit-code semantics, same SARIF output.

bowire scan — vulnerability templates against a target

Runs templates against an HTTP-class target and emits SARIF 2.1.0. Three template sources feed the same engine: the built-in passive checks (always on), the Bowire.VulnDb baseline (curated, ships with the tool), and the projectdiscovery/nuclei-templates set (opt in via --nuclei).

Built-in passive checks fire on every run regardless of template flags: TLS version enumeration (raw SslStream handshakes against 1.0 / 1.1 / 1.2 / 1.3), banner / version disclosure (Server / X-Powered-By / X-AspNet-Version), verbose-error detection (default error pages with stack traces). Each disclosed marker becomes its own SARIF rule so the Code-Scanning dashboard groups correctly.

Read the security-testing ADR →
bash $ bowire scan
# VulnDb baseline + Nuclei templates, one report
$ bowire scan --target https://api.example.com \
              --templates ~/.bowire/vulndb \
              --nuclei ~/nuclei-templates \
              --out findings.sarif --severity medium

  142 template(s) processed:
  [ok]   built-in.tls-1.0          medium
  [VULN] built-in.banner-disclose  low      Server: nginx/1.18.0
  [VULN] CVE-2024-12345            high     /api/v1/admin (header bypass)

  SARIF report -> findings.sarif

bowire fuzz — schema-aware field-level mutation

The field-level fuzzer uses the schema Bowire already knows (OpenAPI / proto / GraphQL / AsyncAPI) to pick payloads that fit the field type. SQL-injection strings don't get thrown at a latitude (lat) field; image.bytes gets magic-byte mutation, not XSS.

Four payload categories ship with curated wordlists (sqli, xss, pathtrav, cmdinj). The baseline-diff oracle compares each mutated response against the unmutated baseline: status change, error-shape divergence, latency spike beyond N standard deviations flags a finding. Findings reuse the same SARIF emitter as scan, so they drop into the same Code-Scanning surface.

Read the technical docs →
bash $ bowire fuzz
# Targeted mutation, baseline-diff oracle
$ bowire fuzz --target https://api.example.com \
              --template recordings/order.bwf \
              --field '$.customer.email' \
              --payloads sqli,xss --out fuzz.sarif

  payloads tried:  42
  baseline runs:    5
  divergent:        3   (status 500, latency >3σ)

bowire jwt — decode, tamper, re-sign

decode splits the header / payload / signature, validates exp / nbf / iat, lists the present claims. tamper probes the classic alg: none acceptance (CVE-2015-9235 class), signs with a chosen secret, lets you override individual claims for the smoke-test sequence.

Pairs naturally with the proxy below: capture a JWT from a real session via bowire proxy, run bowire jwt tamper against it to probe the verification surface, then re-inject the tampered token through the auth-helper's override flag in a follow-up workbench call or scripted assertion.

Read the technical docs →
bash $ bowire jwt ...
# Decode header + payload, flag well-known weaknesses
$ bowire jwt decode <token>

# alg:none downgrade (CVE-2015-9235 class)
$ bowire jwt tamper <token> --alg-none

# Inject a claim, re-sign with a weak secret
$ bowire jwt tamper <token> \
                   --set isAdmin=true \
                   --secret weak123

bowire proxy — intercepting forward proxy, HTTPS MITM

CA-trusted forward proxy with HTTPS MITM (CONNECT hijack, raw TcpListener + SslStream, leaf-cert minting per host, cache that survives restarts). Captured flows stream live into the workbench Proxy view via SSE.

One-click send to recording converts a captured flow into a template that bowire scan, fuzz, or mock can then replay. The auto-generated CA lives at ~/.bowire/proxy-ca.{pfx,crt}; install it once into the trust store of the client you're driving (browser, mobile app under test, scripted runner) and every subsequent run reuses it.

Read the technical docs →
bash $ bowire proxy
# Forward proxy + live workbench Proxy view
$ bowire proxy --port 8888 --api-port 8889

   # proxy        listening on 0.0.0.0:8888
   # workbench    http://localhost:8889/proxy
   # CA exported  ~/.bowire/proxy-ca.crt

Where the templates come from

Three template sources, one engine, one SARIF report. The scanner doesn't care which source a template came from — matchers, payload variables, and severity work the same way regardless.

  • Built-in passive checks. Always on; no template file required. TLS version enumeration drives raw SslStream handshakes against TLS 1.0 / 1.1 / 1.2 / 1.3 in sequence (accepted handshakes on deprecated versions surface as high-severity findings, CWE-326). Banner / version disclosure scans for Server / X-Powered-By / X-AspNet-Version / X-AspNetMvc-Version / Via headers. Verbose-error detection trips default error pages (random path → 404, null-byte URL → 500, malformed query → 4xx) and regex-scans for stack-trace markers (CWE-209).
  • Bowire.VulnDb — curated baseline template set. Ships as a sibling NuGet package (Kuestenlogik.Bowire.VulnDb). Each template is a regular BowireRecording JSON file with three extra fields the scanner consumes: attack: true, a vulnerability metadata block, and a vulnerableWhen predicate. Anchor templates today: gRPC Server-Reflection in production (high), GraphQL __schema introspection in production (medium), REST missing baseline security headers (low). Versioned per release, additions land via PR + CI validation.
  • projectdiscovery/nuclei-templates. 8000+ community-maintained YAML templates. --nuclei <dir> reads them at scan time and translates status / word / regex matchers + matchers-condition + payload matrices + the standard variable set (, , , …) into Bowire's native AttackPredicate DSL. Same engine, two corpora, one report.
  • Your own recordings. A captured probe with attack: true + a vulnerableWhen predicate is a vulnerability template. Capture a real session via bowire proxy, mark the response shape that indicates a vuln, drop the file into your own template directory. Version-control it like any other test fixture.
Template format reference →
flowchart LR
    Passive(["Built-in
passive checks"]) VulnDb(["Bowire.VulnDb"]) Nuclei(["nuclei-templates
(8000+)"]) Own(["Your recordings"]) Engine(["AttackPredicate
engine"]) SARIF[("findings.sarif")] GH(["GitHub
Code Scanning"]) GL(["GitLab
Security Dashboard"]) AzDO(["Azure DevOps"]) Passive --> Engine VulnDb --> Engine Nuclei --> Engine Own --> Engine Engine --> SARIF SARIF --> GH SARIF --> GL SARIF --> AzDO
Templates from any source feed the same AttackPredicate engine. SARIF 2.1.0 is the universal output — every SARIF-aware consumer reads it directly, no translation step.

Wired into CI

SARIF in, GitHub Security tab out. A reusable GitHub Actions workflow ships with the repo — call it from any pipeline, findings land in the calling repo's Code Scanning view.

yaml .github/workflows/security.yml
# Call the reusable workflow from any repo
jobs:
  scan:
    uses: Kuestenlogik/Bowire/.github/workflows/scan-template.yml@main
    with:
      target: https://staging.api.example.com
      templates: ~/.bowire/vulndb
      severity: medium

The workflow installs the CLI, runs the scan, uploads findings.sarif both as a build artifact and via github/codeql-action/upload-sarif@v3 so each finding becomes a Code Scanning alert with stable rule IDs, severity, and remediation copy. GitLab Security Dashboard and Azure DevOps ingest the same SARIF without translation. The DevOps workflow page has the full multi-step pipeline (mock fixture → integration tests → scan → fuzz → SARIF upload).

View the workflow file → Full DevOps workflow →

Roadmap

Four capability tiers from the ADR. Bowire is Apache 2.0 and free / open source — the tiers describe scope and direction, not pricing. Tiers 1 + 2 are shipped; Tier 3 is mostly shipped; Tier 4 is the differentiator pipeline.

  • Tier 1 — Foundation shipped

    The minimum that makes Bowire a credible security tool: bowire scan subcommand, AttackPredicate engine, three seed templates, SARIF 2.1.0 output, built-in TLS / banner / verbose-error passive checks.

  • Tier 2 — Specialty shipped

    Schema-aware field-level fuzzer (bowire fuzz) driven by the frame-semantics layer; JWT toolkit (bowire jwt decode + tamper); the Bowire.VulnDb baseline-template-set repo with per-PR CI validation; Nuclei-template compatibility (--nuclei reads the 8000+ projectdiscovery/nuclei-templates set through the same engine). All four ship in the v1.5+ CLI.

  • Tier 3 — Pro-grade catch-up partial — proxy + Action shipped

    Shipped: intercepting proxy with HTTPS MITM via a self-minted root CA (CONNECT-tunnel hijack, raw TcpListener + SslStream, leaf-cert cache), workbench Proxy view with live SSE flow stream + one-click "send to recording", and the reusable scan-template.yml GitHub Action. Still on the list: sensitive-data scanner (PII / API keys / JWTs in responses), proxy-level breakpoints with conditional pass-through, BOLA / BFLA two-token tests, and broader protocol-specific templates (SignalR brute-force, MQTT topic-enumeration).

  • Tier 4 — Differentiation partial — MCP surface shipped

    Shipped: MCP adapter + bowire mcp serve, so an AI agent can chain discover → record → mark vulnerable → scan through the same primitives a human uses. Still on the list: AI-assisted threat modeling on top of the MCP surface, recording-driven security regression tests as a first-class workflow, multi-protocol attack chains as recordings, automatic OWASP API Top 10 / CWE / CVSS scoring in the SARIF and HTML reports.

Full plan: security-testing ADR on GitHub →

Run a scan

Three template sources, four CLI subcommands, one SARIF report. Read the ADR, point bowire scan at staging.

Found a template gap? Bring it to the crew →