GitLab HTTP Router does not work with cross origin check in workhorse websocket connections
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Problem
As discussed at !205736 (comment 2779869438) we can see that the gorilla websocket library implements a cross-origin check that asserts the Host
header matches the Origin
header at https://github.com/gorilla/websocket/blob/e064f32e3674d9d79a8fd417b5bc06fa5c6cad8f/server.go#L88-L97 .
We know this is broken in GDK and we think it would be broken in production too if we had different hostnames for our new cells.
This does not seem to work with the gitlab-http-router becuase it is swapping out the Host
header when making the requests to workhorse. So in local GDK we end up with Host: gdk.test:3333
and Origin: gdk.test:3000
which do not match.
When using nginx (instead of gitlab-http-router) we don't have this problem as it seems that nginx does not swap the Host
header.
We expect that this will also be a problem in production when we have new cells that have a different Host
header from the one that the user sees in their browser (gitlab.com
). As such we expect any websockets in workhorse features to not work for cells other than the main gitlab.com cell. Those features are:
- Duo Agentic Chat
- Web Terminals
- Some K8s agent features
Solution
We think the right solution might be to update workhorse to compare Origin
against the X-Forwarded-Host
header instead of the Host
header.
It's possible to implement a custom CheckOrigin
as described at https://stackoverflow.com/questions/65034144/how-to-add-a-trusted-origin-to-gorilla-websockets-checkorigin
But we might need additional configuration options for workhorse to support this correctly.