v2.3 turns Bowire into a real API security tool. bowire scan now runs the full OWASP API Security Top 10 — including protocol-specific probes for gRPC, GraphQL, WebSocket, SignalR, Socket.IO, SSE, MCP and MQTT — with a per-scan compliance overview (OWASP / CWE / CVSS). An opt-in active probe tier goes beyond passive checks into deliberately-mutating attacks (MQTT retained-message poisoning, WebSocket compression-bomb / slow-loris, gRPC concurrent-stream fork-bomb, SSE slow-consumption, MCP tool-call injection). A complete out-of-band (OAST) stack lands: an interactsh-compatible client, bowire scan --oast-server, a self-hosted bowire oast serve server, and a manual pen-test panel — so blind SSRF / RCE / XXE that leave nothing in the response can finally be proven. The curated template corpus becomes usable with bowire vulndb update / list, and the AI-assisted layer (threat model, JWT analyzer, OWASP panel, one-button scan, SARIF report) rounds out the lane.
Alongside the security work, the mock server reaches WireMock feature parity (request matchers, body predicates, response templating, scenarios, selective upstream proxy, fault injection, HTTPS, admin CRUD, verification) and a new Monitoring surface runs saved recordings as scheduled health probes with Slack / PagerDuty / OTLP signalers.
196 commits since v2.2.1. No breaking changes — every existing workspace, collection, recording, benchmark and flow loads identically, and all new surfaces are additive and opt-in.
Highlights
OWASP API Security Top 10 — the full suite (#173, #106, #381, #184)
bowire scan --suite owasp-api exercises all ten OWASP API Security Top 10 (2023) entries and rolls the result up per entry: exercised / clean / vulnerable, with the concrete probe behind each. Coverage reaches 10/10 including API6 (business-flow) and API10 (unsafe consumption). Protocol-specific probes go past HTTP: GraphQL introspection + query-depth / complexity / alias-batching, gRPC server-reflection + transport-auth, WebSocket message-size, SSE stream guards, MCP resource-traversal, and MQTT checks. A Compliance tab turns any scan into an OWASP / CWE / CVSS overview with a severity histogram and peak-CVSS readout.
Active probe tier — opt-in, mutating attacks (#395–#400)
Passive checks tell you what a target discloses; the new --active tier tells you what it does under attack. Off by default and gated behind explicit opt-in, it adds MQTT retained-message poisoning + wildcard-subscribe privilege + will-message abuse, WebSocket compression-bomb amplification + slow-loris, SSE slow-consumption, and a gRPC concurrent-stream fork-bomb — each namespacing and cleaning up its own side effects, with an honest verdict about how far it got. Budgets (--active-duration, --active-concurrency, --active-expected-topic) keep it bounded.
Out-of-band detection (OAST) — end to end (#35 Phase 2f)
Blind SSRF / RCE / XXE leave nothing in the response; the only proof is the target reaching out to a host you planted. v2.3 ships the whole chain:
bowire scan --oast-server <url>plants callback hosts into Nuclei OAST templates ({{interactsh-url}},part: interactsh_protocol) and proves a finding only when a genuine callback lands — failing closed when no server is configured, never reporting an unproven blind finding.bowire oast serveis a self-hosted, interactsh-wire-compatible interaction server (DNS + HTTP catchers + register/poll API) — no third-party service, no Go binary.--tokengates it;--oast-tokenauthenticates the client.- A manual OAST panel in the Security rail generates callback payloads to paste by hand and shows a live feed of what hit the catcher — the interactive counterpart for pen-testing, self-hosted.
The crypto (RSA-OAEP + AES-CTR) is pinned against the NIST SP 800-38A vectors and the client↔server pairing is tested against the real server, not in isolation.
bowire vulndb — the template cache (#26)
bowire vulndb update fetches the curated Kuestenlogik/Bowire.VulnDb template set into ~/.bowire/vulndb (latest GitHub release by default; --source for a checkout / tarball / URL and --ref to pin, for air-gapped and reproducible installs). bowire scan reads that cache by default, so an operator runs one update and then scans without repeating --templates. bowire vulndb list shows what's cached.
Monitoring — scheduled health probes (#102)
bowire monitor run <probes> runs saved recordings on a schedule, records every outcome to an append-only ledger, and signals on pass↔fail transitions through opt-in Slack, PagerDuty, and OTLP channels (bowire.monitoring.* instruments). A read-only Monitoring rail renders the live ledger — per-probe status, a latency sparkline, and the outcome history. Sessions resume their cadence across restarts.
Mock server — WireMock feature parity (#401–#411, #430)
The standalone mock server grows from happy-path replay into a full mocking tool: request-matching predicates (query / header / cookie, regex / glob paths, stub priority), body matchers (equalToJson / JSONPath / XPath / JSON-schema / regex), response templating (helpers / math / faker + bodyFileName + a transformer hook), a named scenario state machine, selective upstream proxy (proxyBaseUrl — mock some routes, forward the rest), fault injection (malformed chunks, faults on unmatched requests), HTTPS/TLS (+ a Docker image), per-stub admin CRUD on a running server, and a verification API (verify / findAll / near-misses).
AI-assisted security (#104–#107)
With Kuestenlogik.Bowire.Ai in the process, the Security rail gains an AI threat model (rank endpoints by attack surface), a JWT analyzer (deterministic claim-by-claim flags + an AI narrative), an OWASP API Top 10 panel (per-method status + a concrete probe per risk), a one-button scan that chains threat-model → templates → fuzz → triage → report, and a markdown security report from SARIF with diff-vs-baseline. The deterministic core always runs; the AI layer degrades gracefully when no model is connected.
Scanner foundations
Rounding out the lane: a headless auth-flow runner (bowire scan --auth-flow — login → token chain injected into every probe, secrets from {{env.NAME}}), CVE lookup against discovered server banners, HAR import (Chrome DevTools network tab → recordings, with secret redaction), an endpoint spider with confirm/ignore triage, a schema-aware mutation engine (bowire scan mutate), and Nuclei template compatibility including the Phase 2g DNS-transport translator. bowire scan treats SignalR / Socket.IO / MCP / gRPC / gRPC-Web as HTTP-class transports so their templates run.
Breaking changes
None. v2.3 is purely additive; every new surface is opt-in.
Acknowledgements
Thanks to everyone who exercised the security lane against real targets and reported sharp edges during the 2.3 cycle.
The full commit list, contributors, and compare-URL diff are auto-generated below.
What's Changed
- chore: bump floor to 2.2.0-dev (after v2.2.0) by @thomas-stegemann in #379
- chore: bump floor to 2.2.1-dev (after v2.2.1) by @thomas-stegemann in #380
- chore(actions): Bump github/codeql-action from 3 to 4 by @dependabot[bot] in #373
- chore(actions): Bump actions/setup-node from 4 to 6 by @dependabot[bot] in #371
- chore(actions): Bump actions/checkout from 4 to 7 by @dependabot[bot] in #370
- chore(actions): Bump actions/setup-dotnet from 4 to 5 by @dependabot[bot] in #369
- feat(security): API6 business-flow + API10 unsafe-consumption probes — OWASP suite 10/10 (#381) by @thomas-stegemann in #383
- feat(security): protocol-specific OWASP probes — GraphQL introspection + gRPC reflection/auth (#381) by @thomas-stegemann in #386
- feat(security): OWASP Compliance tab — per-scan OWASP/CWE/CVSS overview (#381) by @thomas-stegemann in #385
- fix(security): scan of a non-http target no longer crashes by @thomas-stegemann in #388
- feat(security): MCP/WS/MQTT protocol probes + Scanner/Ai.Mcp test coverage (#381) by @thomas-stegemann in #387
- feat(security): SSE OWASP protocol probe + text/event-stream guard (#184) by @thomas-stegemann in #389
- test(security): lift Security.Scanner coverage past 90% by @thomas-stegemann in #390
- refactor(keyring): injectable OS-store seam + tests (62% → 97% coverage) by @thomas-stegemann in #391
- feat(security): GraphQL query-complexity / alias-batching probe (API4, #184) by @thomas-stegemann in #392
- feat(security): WebSocket message-size + MCP resource-traversal probes (#184) by @thomas-stegemann in #393
- feat(security): GraphQL query-depth probe + --suite=protocol/all run shape (#184) by @thomas-stegemann in #394
- fix(mock): replay REST response headers + honour recorded Content-Type (#405) by @thomas-stegemann in #412
- feat(mock): request-matching predicates + regex/glob paths + stub priority (#402) by @thomas-stegemann in #414
- feat(sidecar): protocol-version handshake + fix HTTP-transport discovery (#415, #416) by @thomas-stegemann in #419
- docs(sidecar): publish sidecar.schema.json + fix manifest doc/comment drift (#417) by @thomas-stegemann in #420
- feat(mock): request-body matchers — equalToJson / jsonPath / contains / regex (#403) by @thomas-stegemann in #422
- feat(mock): request verification / assertion API — verify + findAll + near-misses (#409) by @thomas-stegemann in #423
- feat(mock): per-stub admin CRUD on a running mock (#404) by @thomas-stegemann in #424
- feat(mock): HTTPS/TLS on the standalone mock server (#410) by @thomas-stegemann in #425
- feat(mock): malformed-response fault + fault-on-miss (#411) by @thomas-stegemann in #426
- feat(mock): named scenario state machine (#408) by @thomas-stegemann in #427
- feat(mock): selective upstream proxy — forward-on-miss + per-stub proxy (#407) by @thomas-stegemann in #428
- feat(mock): response templating — faker + bodyFileName + transformer hook (#406) by @thomas-stegemann in #429
- feat(mock): {{ }} templating + expression helpers + record-through proxy (#430) by @thomas-stegemann in #431
- feat(security): CVE lookup for discovered server banners (#187) by @thomas-stegemann in #432
- feat(security): headless auth-flow runner +
bowire scan --auth-flow(#190) by @thomas-stegemann in #433 - test: fix flaky CI — serialise WorkspaceCommandEdgeCasesTests (global-cwd race) by @thomas-stegemann in #434
- fix(plugins): read plugin DLL with shared write/delete (fix flaky probe test) by @thomas-stegemann in #436
- feat(har): secret redaction, credential detection, idempotent import (#186) by @thomas-stegemann in #435
- feat(security): active (mutating) probe mode + MQTT retained-poisoning (#395) by @thomas-stegemann in #437
- test: silence McpServeCommand console noise in unit tests by @thomas-stegemann in #438
- chore(community): auto-announce releases in Discussions + route questions there by @thomas-stegemann in #439
- feat(security): active MQTT wildcard-subscribe privilege probe (#396) by @thomas-stegemann in #440
- feat(security): active gRPC concurrent-stream fork-bomb probe (#399) by @thomas-stegemann in #441
- feat(security): active timing-based DoS probes — WS slow-loris + SSE slow-consumption (#398) by @thomas-stegemann in #442
- feat(security): active MQTT will-message-abuse probe, rail-isolated (#395) by @thomas-stegemann in #444
- feat(security): active WebSocket compression-bomb probe (#397) by @thomas-stegemann in #443
- feat(security): MCP destructive-tool inventory probe — tool-call injection deterministic slice (#400) by @thomas-stegemann in #446
- feat(security): AI JWT analyzer — deterministic flags + AI narrative (#105) by @thomas-stegemann in #447
- feat(security): AI security report — markdown from SARIF + diff-vs-baseline (#107) by @thomas-stegemann in #448
- feat(security): AI security-scan orchestration engine (#104) by @thomas-stegemann in #449
- feat(security): concrete AI scan-orchestration adapter + endpoint (#104) by @thomas-stegemann in #450
- feat(security): AI OWASP API Top 10 panel — per-method status + probe (#106) by @thomas-stegemann in #451
- feat(security): scanner-backed live probe runner — closes the #104 orchestration wire by @thomas-stegemann in #452
- feat(ai): JWT analyzer workbench surface (#105) by @thomas-stegemann in #453
- feat(ai): OWASP per-method panel + one-button AI security scan UIs (#106, #104) by @thomas-stegemann in #454
- style(ai): CSS for the AI security-suite workbench surfaces (#104–#107) by @thomas-stegemann in #455
- feat(har): server-side HAR export + round-trip golden test (#39) by @thomas-stegemann in #456
- docs(audit): record Trash-as-plugin triage decisions (#339) by @thomas-stegemann in #457
- feat(nuclei): dns transport translator pass (#35 Phase 2g) by @thomas-stegemann in #458
- docs(architecture): Lighthouse scheduled-probes design (#102) by @thomas-stegemann in #459
- docs(architecture): Lighthouse component diagram as Mermaid by @thomas-stegemann in #460
- docs(architecture): rail pipelines & hand-offs by @thomas-stegemann in #461
- docs: fix dead links — add missing rail pages, rename proxy→interceptor by @thomas-stegemann in #462
- test(coverage): raise Sources / Endpoints / Helpers / Mock-Management coverage by @thomas-stegemann in #463
- chore(actions): bump ruby/setup-ruby from 1.315.0 to 1.316.0 by @dependabot[bot] in #464
- chore(deps): Bump the grpc group with 1 update by @dependabot[bot] in #465
- chore(deps): Bump the maplibre group with 2 updates by @dependabot[bot] in #466
- chore(deps): Bump ModelContextProtocol from 1.4.0 to 1.4.1 by @dependabot[bot] in #468
- chore(deps): Bump Testcontainers.Nats from 4.12.0 to 4.13.0 by @dependabot[bot] in #471
- chore(deps): Bump Microsoft.Identity.Web from 4.12.2 to 4.13.0 by @dependabot[bot] in #467
- test(coverage): RecordingSession + Semantics endpoints (34.6% → 43.3%) by @thomas-stegemann in #472
- test(coverage): Auth endpoints + Semantics project-tier by @thomas-stegemann in #473
- test(coverage): Invoke + Channel + Workspace endpoints by @thomas-stegemann in #474
- feat(lighthouse): Core engine — scheduler, ledger, transitions (#102) by @thomas-stegemann in #475
- chore(deps): Bump NATS.Net from 2.8.2 to 3.0.0 by @dependabot[bot] in #470
- feat(lighthouse): recording-replay executor + probe-file loader — end-to-end (#102) by @thomas-stegemann in #476
- refactor(monitoring): rename Lighthouse → Monitoring / bowire monitor (#102) by @thomas-stegemann in #477
- feat(monitoring): bowire monitor CLI command (#102) by @thomas-stegemann in #478
- fix(monitoring): uniform camelCase in the outcome ledger (#102) by @thomas-stegemann in #479
- feat(monitoring): opt-in Slack + PagerDuty signalers + --signal (#102) by @thomas-stegemann in #480
- feat(monitoring): OTLP metrics signaler + bowire.monitoring.* instruments (#102) by @thomas-stegemann in #481
Full Changelog: v2.2.1...v2.3.0