From df643536c03bdd80979a45f057f41dd0dcf9bc92 Mon Sep 17 00:00:00 2001 From: rays Date: Fri, 23 Oct 2026 15:20:55 +0000 Subject: [PATCH] ipx-web drops the header TRUSTED_HEADER names from anyone but the tunnel (#323) ipx trusts [web] trusted_header from Caddy's address, and Caddy stripped only the two Cf-Access-* names from requests not from TUNNEL_PEER. With trusted_header set to anything else (X-Remote-User for another proxy), a request through ipx-web carried it to ipx as Caddy's and was believed: anyone could sign in as anyone. TRUSTED_HEADER, defaulting to Cloudflare's name, is stripped the same way. Production uses Cloudflare's header and sets nothing, so it behaves as before. caddy adapt shows the delete list with and without. Co-Authored-By: Claude Opus 5.5 --- docs/configuration.md | 1 + web/CHANGELOG.md | 1 + web/Caddyfile | 3 +++ 3 files changed, 5 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index cf7415a..bc0fc24 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -206,6 +206,7 @@ The page's container reads only its environment (`web/Caddyfile`): | `WEB_BIND` | Where to listen; `:8080` by default | | `WEB_ROOT` | The built page; `/srv` in the image | | `TUNNEL_PEER` | The one address whose `Cf-Access-*` headers are passed on to ipx: where cloudflared's requests come from. Unset passes none. See [sso.md](sso.md) | +| `TRUSTED_HEADER` | ipx's `[web] trusted_header`, when it is not Cloudflare's: it is passed on from `TUNNEL_PEER` alone too, and dropped from anyone else. Set it to the same name, or anyone could sign in as anyone | | `WEB_TRACING` | `on` sends a span for each request to the collector the `OTEL_*` variables name (`OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf`, `OTEL_SERVICE_NAME`), continuing the page's trace into ipx. Off by default | ipx-directory's settings are in [directory.md](directory.md). diff --git a/web/CHANGELOG.md b/web/CHANGELOG.md index 1a5d652..09eda9e 100644 --- a/web/CHANGELOG.md +++ b/web/CHANGELOG.md @@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security - Open the original, an episode's View in a new tab, the Directory's item links and the `v` key follow a link only when it is a web address. A podcast's `javascript:` or `data:` link was followed as it was (#326). +- `TRUSTED_HEADER` names ipx's `trusted_header` when it is not Cloudflare's, and ipx-web drops that header from anyone but `TUNNEL_PEER` too. Only Cloudflare's were dropped, so with another header anyone could sign in as anyone (#323). ## [1.2.0] - 2026-10-19 diff --git a/web/Caddyfile b/web/Caddyfile index c1f7b5f..d68cb40 100644 --- a/web/Caddyfile +++ b/web/Caddyfile @@ -78,6 +78,9 @@ http://{$WEB_BIND::8080} { @forged not remote_ip {$TUNNEL_PEER:255.255.255.255} request_header @forged -Cf-Access-Authenticated-User-Email request_header @forged -Cf-Access-Jwt-Assertion + # Whatever header ipx's [web] trusted_header names, when it is not Cloudflare's: ipx trusts it + # from this address, and anyone could send it through here (#323). + request_header @forged -{$TRUSTED_HEADER:Cf-Access-Authenticated-User-Email} @api path /api/* /media/* handle @api {