-
Notifications
You must be signed in to change notification settings - Fork 38.8k
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.