---
id: "TECH-202611-c2lguf"
page: "https://infrastack.ai/live/TECH-202611-c2lguf"
kind: "technique"
aliases: []
title: "Spoofed 'Forwarded' header gets past reverse proxies and CDNs, letting attackers fake their IP address or the site's host name in Rails, Spring Boot, Jetty and Symfony apps"
severity: "medium"
cvss: null
epss: null
exploited: false
status: "open"
category: "runtime"
products: [{"name": "Ruby on Rails", "fixed": ["8.1.4.1"], "affected": ">=8.1.0 <8.1.4.1"}, {"name": "Spring Boot", "fixed": ["4.2"], "affected": "<4.2"}, {"name": "Jetty", "fixed": [], "affected": "12.x default config (fix: configuration only)"}, {"name": "Reactor Netty", "fixed": [], "affected": "<1.4"}, {"name": "Symfony", "fixed": [], "affected": "when Forwarded trusted header enabled"}, {"name": "Gorilla handlers", "fixed": [], "affected": "ProxyHeaders"}]
ecosystems: []
tags: ["early-warning", "technique"]
not_affected_if: []
published_at: null
first_seen_at: "2026-11-08T19:02:23+00:00"
updated_at: "2026-11-08T19:02:32+00:00"
sources: [{"source": "analyst", "url": "https://www.lkoskela.fi/blog/2026-11-05-forwarded-without-question/", "first_seen_at": "2026-11-08T19:02:23+00:00", "cites": ["https://www.lkoskela.fi/blog/2026-11-05-forwarded-without-question/"]}]
exploit_sources: []
---

# Spoofed 'Forwarded' header gets past reverse proxies and CDNs, letting attackers fake their IP address or the site's host name in Rails, Spring Boot, Jetty and Symfony apps

Link for people: https://infrastack.ai/live/TECH-202611-c2lguf (this .md is for agents)

A researcher's write-up (lkoskela.fi, 5 Nov 2026) shows that several web frameworks read the standard RFC 7239 'Forwarded' request header and trust it over X-Forwarded-*: Ruby on Rails 8.1 before 8.1.4.1 (client IP only), Jetty 12 in its default setup, Spring Boot before 4.2 when forwarded-header handling is on (FRAMEWORK strategy, or NATIVE on Jetty or Reactor Netty), Symfony when Forwarded support is enabled (host name), and the Gorilla ProxyHeaders handler. Almost no proxy or CDN strips this header by default: Envoy/Envoy Gateway, ingress-nginx, Traefik, Apache, Caddy, Kong, Cloudflare and CloudFront pass it through, and per their docs AWS ALB, Google Cloud and Azure load balancers probably do too. 'Trusted proxy' settings do not help. So a client can fake its IP address (getting around IP allowlists and rate limits, faking log entries) and the host name or protocol (poisoned password-reset links that lead to account takeover, web cache poisoning, redirect loops). The researcher found it common across bug bounty targets. Proof of concept only; no attacks in the wild reported. Rails fixed it in 8.1.4.1. Spring Boot 4.2, Spring 7.1 and Reactor Netty 1.4 changed their defaults. Jetty did not change its default. No CVE known.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- :Ruby on Rails affected >=8.1.0 <8.1.4.1 fixed 8.1.4.1
- :Spring Boot affected <4.2 fixed 4.2
- :Jetty affected 12.x default config (fix: configuration only) fixed no fixed version listed
- :Reactor Netty affected <1.4 fixed no fixed version listed
- :Symfony affected when Forwarded trusted header enabled fixed no fixed version listed
- :Gorilla handlers affected ProxyHeaders fixed no fixed version listed

## How to check

Check whether your app runs on Rails 8.1.x before 8.1.4.1, Jetty 12 (or older), Spring Boot before 4.2 with server.forward-headers-strategy set (FRAMEWORK or NATIVE on Jetty or Reactor Netty), Symfony with the Forwarded trusted header enabled, or Gorilla handlers.ProxyHeaders, AND whether the proxy/CDN in front of it passes the 'Forwarded' header through (the default on Envoy, ingress-nginx, Traefik, Apache, Caddy, Kong, Cloudflare, CloudFront). Test: send 'Forwarded: host=example.com:invalidport'. A 400 Bad Request (often with a Jetty stack trace) means the backend parses Forwarded. Also send 'Forwarded: for=127.0.0.1' and see whether the app logs or uses that IP. On Rails, a 500 when both 'Client-IP' and 'Forwarded: for' are sent means Rails is parsing it. In logs, look for incoming requests carrying a Forwarded header from clients.

## Fix

Make the first reverse proxy, CDN or load balancer drop (or overwrite) any incoming 'Forwarded' header, and X-Real-IP or any other proxy header you do not set yourself. Turn off Forwarded parsing in the app so it reads only the X-Forwarded-* headers your proxy actually sets. Upgrade Rails to 8.1.4.1+ and Spring Boot to 4.2+ (or set the header family explicitly in Spring 7.1 / Reactor Netty 1.4 and older branches). On Jetty, configure ForwardedRequestCustomizer to accept only the headers your proxy handles. Set an allowed-hosts list (Rails config.hosts, Symfony trusted_hosts, Django ALLOWED_HOSTS, ASP.NET AllowedHosts). Do not build password-reset or other absolute links from the request host.

## Timeline

- 2026-11-08T19:02:23+00:00 analyst https://www.lkoskela.fi/blog/2026-11-05-forwarded-without-question/

## Documents

- [describes] Web frameworks overtrust the HTTP Forwarded: header https://news.ycombinator.com/item?id=50415810
- [describes] Forwarded Without Question: How Web Frameworks Overtrust the Forwarded Header https://www.lkoskela.fi/blog/2026-11-05-forwarded-without-question/

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
