Skip to content

Security audit fixes + usage metering + Caddy WS fix#15

Merged
ahmetvural79 merged 1 commit into
mainfrom
fix/security-audit-metering-deploy
Jun 11, 2026
Merged

Security audit fixes + usage metering + Caddy WS fix#15
ahmetvural79 merged 1 commit into
mainfrom
fix/security-audit-metering-deploy

Conversation

@ahmetvural79

Copy link
Copy Markdown
Owner

Summary

Security/correctness fixes from a full audit of both modules, a real dashboard usage-metering feature, and a Caddy WebSocket fix discovered while deploying. All changes build, vet clean, and pass tests (relay with -race).

Security fixes (relay)

  • Magic-link token leak (account takeover): /auth/magic no longer returns the login token in its HTTP response. Gated behind TUNR_DEV_MODE.
  • In-memory auth bypass: /auth/verify no longer mints a JWT for any token when no DB is configured unless TUNR_DEV_MODE=1.
  • Auth rate limiting: /auth/magic is now per-IP rate limited (token spam / user enumeration / email flood).
  • WebSocket origin bypass: /tunnel/connect & /tunnel/tcp used strings.HasSuffix(origin, "tunr.sh") (accepts eviltunr.sh). Now uses host-parsing browserTunnelCheckOrigin.
  • Rate-limiter memory cap: bucket map bounded (maxBuckets) + opportunistic eviction; X-RateLimit-Limit now reports the real per-plan value.

Security/correctness fixes (CLI)

  • Daemon runCommand stub: implemented (was always returning empty → broke Windows PID detection / tunr stop).
  • Internal-API CORS: replaced invalid Access-Control-Allow-Origin: http://localhost:* with loopback-origin reflection.

Feature

  • Real usage metering: per-user request count + bandwidth (Registry.RecordRequest/UserUsage) surfaced via /api/user/profile and /api/user/usage (previously hardcoded 0). Daily reset, unit-tested.

Caddy

  • relay/caddy/Caddyfile: removed manual header_up Upgrade/Connection — these break the WebSocket handshake on Caddy v2 (which proxies upgrades natively). This caused 'upgrade' token not found in 'Connection' header during deploy.

Verified false positives (audit noise, no change)

  • Paddle webhook does verify HMAC-SHA256 with a ±5-min timestamp window before processing.
  • Magic-token consumption does use SELECT … FOR UPDATE.
  • JWT verification enforces alg=HS256 + required expiry.

Deploy

Deployed and verified live on the new relay server (Docker Compose: postgres + relay + Caddy w/ Let's Encrypt wildcard). relay.tunr.sh/health 200, WS /tunnel/connect 101, end-to-end tunnel verified, Paddle webhook 401 on unsigned. See docs/DEPLOY_DOCKER.md (local; docs/ is gitignored).

🤖 Generated with Claude Code

Security fixes:
- relay: never return magic-link token in /auth/magic response (account
  takeover); gate behind TUNR_DEV_MODE. Block /auth/verify JWT minting when
  no DB unless dev mode. Rate-limit /auth/magic per IP.
- relay: fix WebSocket CheckOrigin suffix bypass ("eviltunr.sh") on
  /tunnel/connect & /tunnel/tcp — use host-parsing browserTunnelCheckOrigin.
- relay: bound rate-limiter bucket map (maxBuckets) + opportunistic eviction;
  report real per-plan X-RateLimit-Limit.
- cli/daemon: implement runCommand (was a stub) so Windows PID detection works.
- cli/api: fix invalid "http://localhost:*" CORS — reflect loopback origins.

Feature:
- relay: real per-user request/bandwidth metering (Registry.RecordRequest/
  UserUsage) surfaced via /api/user/{profile,usage} (were hardcoded 0).

Caddy:
- relay/caddy/Caddyfile: drop manual header_up Upgrade/Connection (breaks
  WebSocket on Caddy v2; it proxies upgrades natively).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ahmetvural79
ahmetvural79 merged commit 77f07bc into main Jun 11, 2026
5 of 6 checks passed
@ahmetvural79
ahmetvural79 deleted the fix/security-audit-metering-deploy branch June 11, 2026 11:55
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