Skip to content

security: remediate exploitable vulnerabilities from 2026-07-18 audit#8

Merged
jkyberneees merged 3 commits into
mainfrom
fix/security-findings-2026-07-18
Jul 19, 2026
Merged

security: remediate exploitable vulnerabilities from 2026-07-18 audit#8
jkyberneees merged 3 commits into
mainfrom
fix/security-findings-2026-07-18

Conversation

@jkyberneees

@jkyberneees jkyberneees commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR remediates the exploitable vulnerabilities identified in the 2026-07-18 security audit (sec-findings.md) and updates documentation and tests to match the new behavior. It also fixes a flaky E2E test that was failing on CI.

Security fixes

High

  • V-1 SSRF via upstream redirect — Proxy now uses manual redirect mode by default and enforces redirectAllowlist / redirectSameOrigin before following any redirect.
  • V-2 JWT algorithm confusion — Hardened JWT middleware derives allowed algorithms from the key type, rejects PEM-like strings as HMAC secrets, and enforces a 32-byte minimum for HS256 secrets.
  • V-3 / V-19 Sticky-session exhaustion — Added maxSessions cap, TTL refresh, and unknownCookiePolicy to the sticky-session implementation.
  • V-4 Open redirect on HTTP→HTTPS redirect — Redirect server now requires server.hostname or tls.redirectAllowedHosts before issuing a redirect.

Medium

  • V-5 / V-13 JWT without exp / missing aud/iss — New src/security/jwt-auth.ts requires exp, supports audience/issuer, and validates excludePaths with boundary-aware matching.
  • V-6 excludePaths prefix bypass — Global and route-level rate-limit / auth excludePaths now use boundary-aware matching.
  • V-7 / V-16 Sensitive headers logged — Logger now redacts cookie, set-cookie, and authorization from request/response logs.
  • V-8 / V-12 Non-canonical / double encoding bypass — Path validation rejects overlong encodings and validates after recursive decoding.
  • V-9 Async route error leakage — Router awaits async handlers and the secure error handler sanitizes production errors so stacks/paths are never returned.
  • V-10 TLS options ignoredminVersion and cipherSuites are now mapped to Bun's secureOptions / ciphers.
  • V-11 Simple proxy Host: localhost — Upstream Host header is built from the route target instead of the gateway's own host.
  • V-14 Health-check body timeout — Health-check fetch uses an AbortSignal and reads the response body with a bounded timeout.
  • V-17 Load-balancer double-decrement — Connection counting is now idempotent when a response errors.
  • V-18 Trusted-proxy headerstrustCloudflare / trustXRealIP are now opt-in and used for client-IP extraction and rate-limit keys.

Documentation & examples

  • Updated docs/SECURITY.md, docs/API_REFERENCE.md, docs/AUTHENTICATION.md, docs/TLS_CONFIGURATION.md, docs/LOAD_BALANCING.md, docs/QUICK_START.md, docs/EXAMPLES.md, docs/DOCUMENTATION.md.
  • Updated README.md, AGENTS.md, and examples/security-hardened.ts to reflect new options and defaults.

Tests & CI

  • Added comprehensive tests for JWT auth, proxy redirect handling, rate-limit excludePaths, sticky-session limits, logger redaction, TLS mapping, and the security findings suite.
  • Fixed flaky Hooks E2E Tests > should handle async fallback response generation by reusing the shared failing server instead of spawning a new one on CI.
  • Local: 887 pass / 0 fail with coverage at 99.22% lines / 94.78% funcs.
  • CI tests workflow is now passing on both the push and pull-request events.

Fixes findings documented in sec-findings.md:

High
- V-1 SSRF via upstream redirect (manual redirect mode + allowlist/same-origin)
- V-2 JWT algorithm confusion (algorithm derived from key type, PEM rejection)
- V-3/V-19 Sticky-session unbounded map + TTL refresh (maxSessions, LRU, unknownCookiePolicy)
- V-4 Open redirect on HTTP→HTTPS redirect (require hostname or allowHosts)

Medium
- V-5/V-13 JWT without exp + missing aud/iss (hardened jwt-auth middleware)
- V-6 excludePaths prefix bypass (boundary-aware matching)
- V-7/V-16 Set-Cookie/Authorization logged in plaintext (redact in logger)
- V-8/V-12 non-canonical/double encoding bypass (overlong encoding rejection)
- V-9 Async route errors leaking stack/paths (await router.fetch + sanitized handler)
- V-10 TLS minVersion/cipherSuites ignored (map to Bun secureOptions/ciphers)
- V-11 Simple proxy sending Host: localhost (build upstream URL from route.target)
- V-14 Health-check body read timeout (abort signal across bounded read)
- V-17 Load-balancer connection double-decrement (idempotent flag)
- V-18 trustCloudflare/trustXRealIP opt-in

Also fixes route-level rateLimit.excludePaths to be boundary-aware.

Adds src/security/jwt-auth.ts and comprehensive tests. Updates docs/SECURITY.md,
docs/API_REFERENCE.md, docs/AUTHENTICATION.md, docs/TLS_CONFIGURATION.md,
docs/LOAD_BALANCING.md, docs/QUICK_START.md, docs/EXAMPLES.md, AGENTS.md,
README.md and examples/security-hardened.ts.

Tests: 887 pass / 0 fail. Coverage: 99.22% lines / 94.78% funcs.
@jkyberneees
jkyberneees merged commit fe98171 into main Jul 19, 2026
5 checks passed
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.

1 participant