fix(server): include x-forwarded-host in board mutation origin check

Behind a reverse proxy with a custom port (e.g. Caddy on :3443), the
browser sends an Origin header that includes the port, but the board
mutation guard only read the Host header which often omits the port.
This caused a 403 "Board mutation requires trusted browser origin"
for self-hosted deployments behind reverse proxies.

Read x-forwarded-host (first value, comma-split) with the same pattern
already used in private-hostname-guard.ts and routes/access.ts.

Fixes #1734
This commit is contained in:
Matt Van Horn 2026-03-25 00:06:43 -07:00
parent cbca599625
commit d0e01d2863
No known key found for this signature in database
2 changed files with 13 additions and 1 deletions

View file

@ -84,6 +84,17 @@ describe("boardMutationGuard", () => {
expect(res.status).toBe(204);
});
it("allows board mutations when x-forwarded-host matches origin", async () => {
const app = createApp("board");
const res = await request(app)
.post("/mutate")
.set("Host", "127.0.0.1")
.set("X-Forwarded-Host", "10.90.10.20:3443")
.set("Origin", "https://10.90.10.20:3443")
.send({ ok: true });
expect(res.status).toBe(204);
});
it("does not block authenticated agent mutations", async () => {
const middleware = boardMutationGuard();
const req = {