Changelog
Version v1.1.0 — security hardening
v1.1.0 is a security-hardening release. Three critical and five high-severity CVEs patched, SSH command composition hardened against injection, global rate limiting added, Slack webhook validation tightened. All backwards-compatible for self-hosters — pull, restart, migrations run, done.
⚠️ Behavior change to be aware of
Global rate limiting is now active. 100 requests per minute per client IP, across all routes except /health and /api/client-config. If you have programmatic integrations that poll aggressively, they may start getting HTTP 429 responses with a retryAfterSeconds field. Adjust client polling or loosen the limit via custom config if needed.
Security fixes
Patched CVEs
- fast-jwt 5.0.6 → 6.2.2 (via
@fastify/jwt9 → 10 — PR #69) closes:- Critical — Cache confusion via
cacheKeyBuildercollisions returning claims from a different token - Critical — Incomplete fix for CVE-2023-48223 (JWT algorithm confusion via whitespace-prefixed RSA keys)
- High —
fast-jwtaccepts unknowncritheader extensions (RFC 7515 violation) - Moderate — Stateful RegExp non-deterministic allowed-claim validation (logical DoS)
- Moderate — ReDoS in
allowed*claim validation during token verification
- Critical — Cache confusion via
- Numerous additional CVEs patched via grouped dependency updates (backend, frontend, CLI, agent, Docker).
Code-level hardening
- Slack webhook URL validation (#63) — replaced a substring check (
.includes('hooks.slack.com')) with propernew URL(url).hostname === 'hooks.slack.com'. URLs likehttps://evil.com/?x=hooks.slack.comare now correctly rejected. - SSH command injection surface (#67, #68) — introduced
shellEscape()insrc/lib/ssh.tsand applied it at every call site where a user-configured value (paths, container names, etc.) is interpolated into a shell command string. Coversdeploy,database-backup,database-query-executor,config-files,agent-deploy, and service log streaming. Double-quoting alone was insufficient —$, backticks, and$()were still interpreted. - Global rate limiting (#64) —
@fastify/rate-limitregistered globally, 100 req/min/IP,/healthand/api/client-configallow-listed so external monitors don’t get throttled.
Dependencies
Significant bumps:
@fastify/jwt9.1.0 → 10.0.0 (security)@fastify/multipart9.4.0 → 10.0.0@fastify/cors10.x → 11.x (bundled in grouped backend security update)zod3.x → 4.x (backend — with forward-compatible code changes in #62)fast-jwt5.0.6 → 6.2.2 (transitive via@fastify/jwt)@types/node22.x → 25.x- Docker base image
golang:1.22-alpine→1.26-alpine - CLI Go toolchain 1.22 → 1.25
- Plus grouped backend-security, frontend-security, cli-minor-and-patch, agent-minor-and-patch, actions-version groups.
Developer experience
shellEscape()helper exported fromsrc/lib/ssh.ts— wrap any value interpolated into a command string.- New convention documented in
CLAUDE.md(Backend Patterns) anddocs/development/testing-guide.md(Unit test rule 7 on keepingvi.mockfactories in sync with module exports). - Dependabot grouping (#50) — security updates and minor+patch bumps now land as one PR per ecosystem per week, instead of dozens of individual PRs.
Upgrading
docker pull ghcr.io/bridgeinpt/bridgeport:latestdocker stop bridgeport && docker rm bridgeport && docker run -d ... # same args as beforeMigrations apply automatically on first start. No manual steps.
Full changelog
https://github.com/bridgeinpt/bridgeport/compare/v1.0.0…v1.1.0