Note
This is a focused security release for Portway. It hardens authentication and rate limiting against abuse, with one behavior change worth reviewing (see the migration notes). There are no changes to routes, configuration formats, or runtime behavior for correctly configured instances. Backup your application folder before upgrading as usual.
Fixes in v1.6.1:
Security-related fixes:
- Fail-closed environment authentication: An environment with
Authentication.Enabledset totruebut no methods configured now denies the request instead of silently allowing it. This was the one place a misconfiguration could leave an environment open; it now fails safe. - Credential endpoints are always throttled: The Web UI login and CSRF-token endpoints are no longer exempt from rate limiting, and the exemption for other UI traffic now requires a cryptographically valid session cookie rather than a merely present one. A forged cookie can no longer skip the limiter.
- Real client IP behind reverse proxies: A new optional
ForwardedHeaderssection lets you register trustedKnownProxiesandKnownNetworks, soX-Forwarded-Foris honored only from proxies you trust. Per-IP rate limiting and the Web UI network gate then see the real client IP. Left empty, the header is ignored exactly as before. - Invalid-token flood protection: Token verification now negative-caches misses for a short window, so a flood of random bearer tokens can no longer force a full-table PBKDF2 rescan on every request.
- Constant-time secret comparison: Environment API keys, Basic passwords, Bearer tokens, and HMAC signatures are compared with
CryptographicOperations.FixedTimeEquals, removing a timing side-channel on those secrets. - Unsigned JWTs refused: A JWT environment method configured without a
SecretorPublicKeynow rejects the request instead of accepting an unsigned token. - IPv6 SSRF coverage: The proxy block list now covers IPv6 private ranges (
fc00::/7,fe80::/10) and unwraps IPv4-mapped IPv6 addresses before checking them, closing gaps in the outbound URL validator. - Security posture signal: The Settings posture panel now reports
trusted_proxies_configured, so you can see at a glance whether reverse-proxy client-IP recovery is set up.
Other improvements:
- refactor(rate-limiting): Removed a duplicate, unused
UseRateLimiterpipeline extension so the middleware can only be constructed with the resolved admin key. - fix(rate-limiting): The rate limiter now reads the same resolved
WebUi:AdminApiKeyas the Web UI authentication, so the exemption check and the auth middleware always agree. - tests: Suite grew from 335 to 345 tests, covering fail-closed environment auth, keyless-JWT rejection, session-cookie validation for the rate-limit exemption, credential-endpoint throttling, and the token negative-cache.
Migration guide
No breaking changes to routes, configuration formats, or runtime behavior. Two things are worth knowing:
- Environments with authentication enabled but no methods now return
401. If an environment hadAuthentication.Enabled: truewith an emptyMethodslist, it was previously open to any request and now denies. Add at least one method, or setEnabled: false, to restore access. - Running behind a reverse proxy? Register it. If a proxy sits in front of Portway, set
ForwardedHeaders:KnownProxies(and/orKnownNetworks) so per-IP rate limiting and the Web UI network gate see the real client IP. Without it,X-Forwarded-Foris ignored and all clients appear as the proxy IP, exactly as in earlier releases.
Check our documentation for guidance. If you encounter issues, open a new Issue.
Full Changelog: v1.6.0...v1.6.1