Skip to content

Released version 3.4.1

Latest

Choose a tag to compare

@dg dg released this 27 Aug 04:25
· 8 commits to master since this release

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-supplied Forwarded header can no longer spoof the address or host. If your proxy uses the Forwarded header, set http: proxyHeaders: forwarded (or both).
  • getRemoteAddress() returns null instead 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 / $xForwarded flags of RequestFactory::setProxy() let you tell Nette exactly which forwarding headers your proxy manages – and ignore the rest.
  • RequestFactory::setBaseUrl() and the http: baseUrl option give CLI runs (cron, tasks, MCP servers) a real request URL, so %baseUrl%, LinkGenerator, template $baseUrl and 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 Forwarded into 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 $path or $domain as given: '' now yields a host-only cookie or the / path instead of silently falling back to the configured defaults. Only null means "not specified".