Executive brief
Tinyauth is a forward-auth proxy that enforces per-application access control rules for multi-app SSO deployments. An authenticated but unprivileged user can bypass the `users.allow`, `groups`, and IP-allowlist restrictions for any app on the same instance by requesting it with a mixed-case hostname (e.g., `IMMICH.example.com` instead of `immich.example.com`). Since the ACL lookup fails to find the app's rules and falls back to an empty configuration, any logged-in user is authorized to reach apps they should be denied access to, granting unauthorized read and write access to sensitive application data.
Technical details
Tinyauth performs per-app authorization by looking up the forwarded hostname in its ACL configuration using case-sensitive string comparisons (`config.Config.Domain == domain` and `strings.SplitN(domain, ".", 2)[0] == app`). HTTP hostnames are case-insensitive per RFC 4343, and reverse proxies (Traefik, Caddy, nginx, Envoy) route requests case-insensitively but forward the mixed-case host verbatim in headers like `X-Forwarded-Host`. When the lookup misses on a case mismatch, `GetAccessControls` falls back to `DockerService.GetLabels`, which returns an empty `config.App{}` with a nil error (fail-open behavior). An empty App authorizes any logged-in user because the default filters (`users.allow`, `oauth.groups`, etc.) return true when empty. The bypass affects all four proxy integrations and applies to any authenticated user not in the target app's allowlist. Patches are available in v5.1.2 or later.
Affected products
- Tinyauth tinyauth < 5.1.2
Timeline
- 2026-09-22: disclosed
- 2026-09-22: patched: v5.1.2 available