Description
Spring's ForwardedHeaderFilter
handles the header value X-Forwarded-Proto: wss
incorrectly. The class has hardcoded checks for "http" and "https", which is in line with the widely held assumption that these are the only valid values (see e.g. MDN and other sources when searching for the header name on the web).
But X-Forwarded-Proto
is not standardized, and at least one popular proxy, Traefik, has decided to use "ws" and "wss" in the header, see traefik/traefik#6388. We have run into problems with Spring because of that. Also Tomcat has added "ws"/"wss" as supported values: apache/tomcat#311
I suggest that "wss" should be a supported value and handled consistently like "https".
ForwardedHeaderFilter
and its dependency UriComponentsBuilder.fromHttpRequest(request)
have hardcoded checks for "http" and "https" in multiple places ([1], [2]). Depending on which other X-Forwarded-*
headers are present, it maps a request on port 443 and X-Forwarded-Proto: wss
to the following ServletRequest
properties: scheme=wss, port=80, secure=false
or scheme=wss, port=443, secure=false
. This seems clearly incorrect.
Based on my observations I would propose that X-Forwarded-Proto: wss
gets mapped into the ServletRequest.scheme
value "https" (and "ws" -> "http") because that seems the most compatible way. Leaving "wss" in the ServletRequest.scheme
seems to lead to problems. A same-origin check that compares the value of the Origin
header (where "https" would be the protocol) with the servlet request url would fail. I also know of at least one library that fails completely when it encounters scheme=wss
in the ServletRequest
object.