Connection: Upgrade
header, such as for a websocket connection, the reverse proxy will maintain the persistent connection between the client and server, allowing for the continuous communication needed for these procotols. For a H2C Connection, the RFC requires 3 headers to be present:Connection: Upgrade
variant, where the HTTP2-Settings
value is omitted from the Connection
header.”proxy_pass
URL (the endpoint the proxy forwards the connection) was pointing to a specific path such as http://backend:9999/socket.io
the connection will be stablished with http://backend:9999
so you can contact any other path inside that internal endpoint abusing this technique. So it doesn't matter if a path is specified in the URL of proxy_pass.Sec-WebSocket-Version
. Proxy doesn't validate Sec-WebSocket-Version
header and thinks that Upgrade request is correct. Further it translates request to the backend.426
because protocol version is incorrect inside header Sec-WebSocket-Version
. However, reverse proxy doesn't check enough response from backend (including status code) and thinks that backend is ready for WebSocket communication. Further it translates request to the client./api/socket.io/
and healthcheck API on path /api/health
.u
controls URL. Backend reaches external resource and returns status code back to the client.Upgrade: websocket
. NGINX thinks that it's a normal Upgrade request, it looks only for Upgrade
header skipping other parts of the request. Further proxy translates request to the backend.101
. Backend translates that response to the reverse proxy. Since NGINX validates only status code it will think that backend is ready for WebSocket communication. Further it translates request to the client.