Skip to content

SWI-11363 Add CONTRIBUTING guide + harden webhook auth and outbound fetch handling#14

Merged
kshahbw merged 14 commits into
mainfrom
adapter/contributing-guide
Jul 16, 2026
Merged

SWI-11363 Add CONTRIBUTING guide + harden webhook auth and outbound fetch handling#14
kshahbw merged 14 commits into
mainfrom
adapter/contributing-guide

Conversation

@kshahbw

@kshahbw kshahbw commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Two pieces of work land together here:

  1. A CONTRIBUTING guide — contributor setup, workflow, and conventions.
  2. Webhook & callback hardening — the adapter now authenticates the webhooks Bandwidth sends it, constrains where it makes server-side requests, and compares credentials in constant time.

Contributing guide

Adds CONTRIBUTING.md covering local setup, the test/typecheck workflow, and project conventions.

Webhook & callback hardening

  • Constant-time credential comparison. All REST-facade auth checks route through a single safeEqual helper (crypto.timingSafeEqual), replacing the previous !== string comparisons.
  • Inbound webhook authentication. All /bw/* routes now require HTTP Basic auth (WEBHOOK_USER / WEBHOOK_PASSWORD), matching Bandwidth's native CallbackCreds. This is a distinct secret from the Twilio-compat REST credential. The translator stamps the same credentials onto the BXML callback verbs it emits, so Bandwidth presents them on continuation callbacks.
  • Outbound fetch guard. Customer-directed fetches are validated first: only http/https, and loopback/link-local/private ranges (IPv4, IPv6, IPv4-mapped) are refused. Redirects disabled; request timeout applied.
  • Loopback listen default. Listen host defaults to 127.0.0.1; set HOST=0.0.0.0 to expose it.
  • Optional host allowlist. EGRESS_ALLOW_HOSTS switches outbound fetches to a strict default-deny allowlist.
  • SECURITY.md documenting the auth model, the egress guard (and its defense-in-depth boundary), and setup.

⚠️ Config changes for operators

  • New required env vars: WEBHOOK_USER, WEBHOOK_PASSWORD (also set matching CallbackCreds on your Bandwidth Voice application).
  • Breaking default: listen host is now 127.0.0.1 — containerized/exposed deployments must set HOST=0.0.0.0.
  • Optional: EGRESS_ALLOW_PRIVATE=1 (local dev against localhost/LAN), EGRESS_ALLOW_HOSTS (strict allowlist).

Testing

Full suite green: 303/303 (npm test), typecheck clean. Adds coverage for the egress guard (range classification, IPv6-literal + IPv4-mapped, redirect/timeout), inbound auth (401 on missing/wrong creds, REST facade not unlocked by webhook creds), and callback-credential stamping.

🤖 Generated with Claude Code

kshahbw and others added 13 commits July 14, 2026 10:37
Sets community-supported expectations (no dedicated dev team, PRs/issues
looked at by a Bandmate as bandwidth allows), plus issue/PR guidance,
PII guardrails, and the test/typecheck checklist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Strip brackets from IPv6-literal hostnames before the isIP() fast path so
literals like https://[::1]/ are classified against the blocklist instead
of silently falling through, and wrap DNS resolution failures (including
the default resolver's ENOTFOUND throw) in EgressBlockedError so callers
that pattern-match on the typed error get a consistent fail-closed result.
Add an onRequest hook that enforces HTTP Basic auth (via safeEqual) on
every /bw/* route, gated by new required AdapterConfig fields
webhookUser/webhookPassword. The REST facade keeps its own separate
authOk check and is unaffected. Updates all existing tests that hit
/bw/* or build an AdapterConfig to supply the new fields and, where
applicable, the Authorization header, plus the local bench script.
Update stale test count in README and make SECURITY.md / egress-guard.ts
honest about the range denylist not defending against DNS rebinding.
Harden webhook authentication and outbound fetch handling
@kshahbw
kshahbw requested review from a team as code owners July 15, 2026 17:31
@bwappsec

bwappsec commented Jul 15, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@kshahbw kshahbw changed the title Add CONTRIBUTING guide + harden webhook auth and outbound fetch handling SWI-11716 Add CONTRIBUTING guide + harden webhook auth and outbound fetch handling Jul 15, 2026
@kshahbw
kshahbw merged commit 23dc6ef into main Jul 16, 2026
6 checks passed
@kshahbw
kshahbw deleted the adapter/contributing-guide branch July 16, 2026 13:47
@kshahbw kshahbw changed the title SWI-11716 Add CONTRIBUTING guide + harden webhook auth and outbound fetch handling SWI-11363 Add CONTRIBUTING guide + harden webhook auth and outbound fetch handling Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants