This release hardens the reverse-proxy trust model: the real client address, scheme and host are now resolved correctly from multi-hop Forwarded and X-Forwarded-* headers, and you can choose which of them your proxy is allowed to speak for. On top of that, CLI scripts finally get a meaningful request URL.
💥 Breaking Changes
- Applications configured through the DI extension now trust only
X-Forwarded-*headers from a trusted proxy by default, so a client-suppliedForwardedheader can no longer spoof the address or host. If your proxy uses theForwardedheader, sethttp: proxyHeaders: forwarded(orboth). - getRemoteAddress() returns
nullinstead of a non-IP string when the innermost forwarded value is not a valid IP address (e.g. an obfuscated identifier or a broken chain).
✨ New Features
- proxyHeaders option (
both|xForwarded|forwarded|none) and the$forwarded/$xForwardedflags of RequestFactory::setProxy() let you tell Nette exactly which forwarding headers your proxy manages – and ignore the rest. - RequestFactory::setBaseUrl() and the
http: baseUrloption give CLI runs (cron, tasks, MCP servers) a real request URL, so%baseUrl%, LinkGenerator, template$baseUrland assets work outside the web server too. It kicks in only when no host can be detected, so web requests are unaffected.
🐛 Bug Fixes
- Trusted-proxy resolution now parses
Forwardedinto proper RFC 7239 hops and picks the client by stripping trailing trusted proxies, instead of blindly trusting the leftmost, client-spoofable value; scheme and host are taken from the same hop as the selected address and no longer discarded on multi-hop headers. - Response::setCookie() treats an explicitly empty
$pathor$domainas given:''now yields a host-only cookie or the/path instead of silently falling back to the configured defaults. Onlynullmeans "not specified".