| Version | Supported |
|---|---|
| >= 1.4.0 | Yes |
| 1.3.0 – 1.3.4 | Critical fixes only |
| < 1.3.0 | No |
Only the latest minor release receives feature-level security patches. The 1.3.x line continues to receive critical fixes for vulnerabilities that cannot be mitigated by upgrading. Upgrade to the latest 1.4.x for all fixes.
v1.4.1 ships the middleware × driver integration milestone, the dynamic worker scaler, memcached cluster failover, and a sweep of driver/middleware hot-path optimizations. Security-relevant changes:
middleware/overloadshedding ladder: 5-stage controller with CPU- queue-depth + tail-latency-EMA signals returns 503 + Retry-After at saturation. Designed to keep an overloaded process from cascading into total unavailability under DoS-shaped traffic. Defaults are conservative; the alloc-budget guard test pins the Normal-stage path at zero allocations so the middleware itself cannot become a bottleneck.
middleware/idempotencylock state machine: client-suppliedIdempotency-Keyheader is matched against astore.SetNXer-backed lock entry; concurrent duplicates while the original is in-flight return 409 (no double-execute), and replays serve the cached response for the configured TTL. Lock entries are released on handler completion or expire afterLockTimeoutso a crashed handler does not permanently block the key. Constant-time key comparison viasubtle.ConstantTimeCompare.middleware/cacheCache-Control honoring: by default, responseCache-Controldirectives (no-store,private,max-age) cap the effective TTL.Set-Cookieis excluded from stored headers by default to prevent session-cookie leakage between users.Varyheader components are folded into the cache key to prevent cross-user replay on shared keys.middleware/storeunifiedKVinterface: session, csrf, ratelimit, cache, idempotency, and JWKS cache all share the same byte-level contract.Prefixednamespace helper prevents key collisions when a single Redis / Postgres instance backs multiple middlewares; without it a CSRF token store and a session store could overwrite each other. Backed adapters: in-memory LRU (sharded), Redis (GETDELfor atomic single-use, falls back toGET+DELon Redis < 6.2 viaOldRedisCompat), Postgres (ON CONFLICTupsert + background expiry sweep), memcached.Context.SetHeaderTrust/Context.AppendRespHeader: new fast-path response-header verbs that skip the CRLF / NUL sanitize scan. Documented as caller-asserted invariants — used internally byrequestid,secure, andratelimitafter one-time validation at middleware construction. Not for user-supplied input. The fullSetHeader/AddHeaderverbs continue to sanitize.auto_cache_statementsdefault flip:Pool.OpenandNewConnectornow defaultauto_cache_statements=true(matching pgx). Cached prepared statements are scoped per connection and discarded on conn close; no cross-conn leakage. Opt out per DSN withauto_cache_statements=falsefor environments that need the simple-query semantics (e.g. server-side trigger-driven caches).- memcached cluster failover:
pickNodesuccessor walk is deterministic so a node-down event does not silently route writes to a different shard's read-replica.recordResultuses a hysteresis threshold to prevent thrashing. Stale reads during failover are surfaced as transient errors rather than silently served from a potentially-stale node.
v1.4.0 introduces the native PostgreSQL, Redis, and memcached drivers plus H2C upgrade support and the EventLoopProvider plumbing. Security posture is conservative:
- TLS not implemented:
driver/postgresrejectssslmode=require / verify-ca / verify-fullwithErrSSLNotSupportedrather than silently downgrading.sslmode=prefer / allowemit a stderr warning before downgrading to plaintext.driver/redisrejectsrediss://URLs atNewClienttime. Until first-class TLS lands, deploy over VPC, loopback, or terminate at a sidecar TLS proxy. - PG SCRAM-SHA-256 only: cleartext / MD5 / trust + SCRAM-SHA-256 (without channel binding) are supported. GSS, SSPI, Kerberos, SCRAM-SHA-256-PLUS, and other SASL mechanisms are rejected — no silent fallback to a weaker auth path.
- Driver
WithEnginedeadlock fix: when an engine'sWorkerLoopdoes not implementsyncRoundTripper, drivers fall back to direct mode (Go netpoll) instead of deadlocking. Prevents a pool-exhaustion DoS on a misconfigured server. - H2C upgrade single-token Upgrade enforcement: RFC 7540 §3.2
requires
Upgrade: h2cto be the sole token. Multi-token Upgrade headers (e.g.Upgrade: websocket, h2c) are disqualified to prevent ambiguity attacks against simultaneous WebSocket / H2 negotiation.
v1.3.4 introduces engine-integrated WebSocket/SSE plus a follow-up middleware audit. Security-relevant changes:
- WebSocket permessage-deflate decompression cap:
truncWriterwas rewritten to correctly reassemble the tail-4 sync-marker window when a flate writer emits sub-4-byte trailing chunks (Autobahn 12.1.4-12.1.10 regression on v1.3.3). The decompression path now bounds output viaio.LimitReadercapped by the per-connectionReadLimit, preventing decompression-bomb DoS. - WebSocket missing-Origin policy: when
Config.CheckOriginis nil, connections without anOriginheader onhttps://are rejected by default (CSRF mitigation for browser-origin assumptions). Non-browser clients should set an explicitCheckOriginto allow Origin-less upgrades. - SSE comment field sanitization:
Client.SendCommentnow strips\rand\nfrom comment text, matching the treatment ofidandeventfields. Prevents synthetic-event injection if a handler forwards user-supplied text as a comment. - Swagger ClientSecret removed:
OAuth2Config.ClientSecretwas rendered into served HTML in plaintext; the field is removed and the documentation now requires PKCE for browser flows. - basicauth HashedUsers default removed: SHA-256 is no longer the
default password hash. Callers must supply
HashedUsersFunc(bcrypt/scrypt/argon2 example in package docs); the existingHashPasswordhelper is retained but flagged as fast-hash for deterministic identifiers, not credentials. - Engine-integrated WebSocket auditability: the
H1Statepause/ resume API surface (OnError,PauseRecv,ResumeRecv,IdleDeadlineNs,OnDetachClose) is documented as the stable middleware↔engine contract for long-lived connections; changes require a major version bump.
v1.3.3 includes security-hardened defaults in three new middleware packages:
- Pprof loopback-only default: The pprof middleware restricts access to loopback IPs (127.0.0.1, ::1) by default. Exposing Go profiling data to untrusted networks reveals goroutine stacks, heap contents, and source code paths.
- Static path traversal protection: The static middleware uses celeris's FileFromDir (with symlink resolution and prefix verification) for OS filesystem access. For fs.FS, paths are cleaned and .. components are rejected.
- Swagger path-only interception: The swagger middleware only responds to exact path matches under its BasePath ({BasePath}/, {BasePath}/spec) and ignores all other requests. OpenAPI specs may reveal internal API structure — restrict access with upstream auth middleware or network-level controls.
v1.3.2 includes a security fix and hardening in the new resilience middleware:
- Singleflight cross-user data leakage (fixed): The default deduplication key now includes
AuthorizationandCookierequest headers. Without this, concurrent authenticated requests to the same endpoint would be coalesced, leaking one user's response (including PII, session cookies) to another user. CustomKeyFuncimplementations must incorporate user identity for authenticated endpoints. - Singleflight multi-value header replay (fixed): Waiter response replay now uses
SetResponseHeaders(bulk replace) instead of aSetHeaderloop, preserving multi-value headers likeSet-Cookie. The previous implementation dropped all but the last value for duplicate header keys. - Circuit breaker panic recording: Handler panics are now recorded as failures in the sliding window via
defer/recoverbefore re-panicking. Previously, panics bypassed the circuit breaker entirely, making it blind to panic-heavy failure modes. - Circuit breaker validation hardened:
validate()now rejects negativeCooldownPeriod,HalfOpenMax < 1,WindowSize < 10ms, andMinRequests < 1. Previously onlyThresholdwas validated, allowing configurations that caused division-by-zero panics or permanently stuck breakers.
v1.3.1 includes security hardening in the new HTTP transport middleware and core:
- Scheme() trust model:
Context.Scheme()no longer readsX-Forwarded-Protofrom untrusted clients. Only the proxy middleware (which validates againstTrustedProxies) can set the scheme override. This preventsHTTPSRedirectbypass by direct-connect attackers. - Proxy host validation:
X-Forwarded-Hostis validated against CRLF injection, null bytes, path traversal (/,\), query injection (?,#), userinfo injection (@), and a 253-byte DNS length cap. - Proxy IP validation:
X-Real-IPand custom headers (e.g.,CF-Connecting-IP) are parsed withnetip.ParseAddr— non-IP values are rejected. - Method override target restriction:
TargetMethodswhitelist (default: PUT, DELETE, PATCH) prevents overriding POST to arbitrary methods like CONNECT or TRACE. - Negotiate q=0 exclusion:
Accept-Encodingentries withq=0are now correctly treated as "not acceptable" per RFC 9110, including wildcard exclusions (e.g.,*, br;q=0excludes brotli). - Redirect code validation: Only valid redirect codes (301, 302, 303, 307, 308) are accepted. Non-redirect codes like 304 are rejected at init time.
- Compress BREACH warning: Documentation warns about BREACH attacks when compressing HTTPS responses containing both user-controlled input and secrets.
v1.3.0 includes hardening identified during a comprehensive 24-agent automated security review:
- CORS:
MirrorRequestHeadersnow validates tokens against RFC 7230 tchar charset with size/count limits (prevents header injection).AllowCredentialswith wildcard subdomain origins now panics at init. - JWT: Error classification distinguishes expired vs malformed vs invalid tokens. JWKS keys pre-fetched eagerly to eliminate first-request blocking.
- BasicAuth: Case-insensitive "Basic" scheme matching per RFC 7617.
- KeyAuth:
Varyheader on 401 responses for header-based lookups (cache correctness). - Recovery: Exported sentinel errors (
ErrPanic,ErrBrokenPipe,ErrPanicContextCancelled,ErrPanicResponseCommitted) for programmatic error matching.
Versions prior to 1.3.0 contain known security gaps in CORS header mirroring, JWT error disclosure, and BasicAuth scheme parsing. Versions prior to 1.2.0 contain known vulnerabilities in the HTTP response writer, cookie handling, header sanitization, and the Detach() streaming mechanism. We strongly recommend upgrading immediately.
If you discover a security vulnerability in celeris, please report it responsibly.
Do not open a public GitHub issue for security vulnerabilities.
Instead, please email security@goceleris.dev with:
- A description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We will acknowledge receipt within 48 hours and aim to provide a fix within 7 days for critical issues.
This policy covers the core github.com/goceleris/celeris module and all in-tree middleware, including:
- HTTP protocol parsing (H1, H2)
- I/O engines (io_uring, epoll, std)
- Request routing, pre-routing middleware (
Server.Pre()), and context handling - The net/http bridge adapter
- Response header sanitization (CRLF, null bytes, cookie attributes)
- Connection lifecycle management (Detach, StreamWriter, pool safety)
- Body size enforcement (MaxRequestBodySize across H1, H2, bridge)
- Callback safety (OnExpectContinue, OnConnect, OnDisconnect)
- All in-tree middleware packages (
middleware/) - The
middleware/storeunifiedKVsubstrate plus the bundled adapters (in-memory LRU, Redis, Postgres, memcached) - Native drivers:
driver/postgres,driver/redis,driver/memcached(wire-protocol parsers, auth handshakes, cluster failover state) - Sub-module middleware (
middleware/compress,middleware/metrics,middleware/otel,middleware/protobuf)
- The deprecated
github.com/goceleris/middlewaresmodule (archived, retracted) - Third-party middleware not in this repository
- Application-level vulnerabilities in user code