Summary
Tinyauth may compare forwarded hostnames case-sensitively even though reverse proxies route equivalent hostnames without regard to case. An authenticated low-privilege user could use a differently cased hostname to bypass per-application access controls when the lookup returns an empty, permissive access-control object.
Affected context
The issue may affect Tinyauth deployments operating behind reverse proxies that normalize hostname comparisons case-insensitively. It is relevant where per-application access controls are resolved from forwarded hostnames through static configuration or Docker labels, and where an unmatched lookup is treated as having no restrictions. Unauthenticated users generally remain subject to login requirements and global login-time allowlists.
Exploit preconditions
- Attack surface: The reverse-proxy request path and forwarded-hostname access-control lookup
- Required access: An authenticated account with low privileges
- Trigger point: A request using a hostname whose letter casing differs from the configured application hostname
- Why exploitation is possible: Case-sensitive lookups can fail to find the configured application, producing an empty access-control object that the proxy handler interprets as permissive
Why this happens
The underlying bug is inconsistent hostname canonicalization across trust boundaries. Reverse proxies may treat hostnames case-insensitively, while Tinyauth access-control lookups compare forwarded hostnames case-sensitively through static ACL and Docker-label resolution paths. When the lookup misses the intended application, the resulting empty policy is treated as an allow decision rather than as an error or restricted state. This maps primarily to CWE-178: Improper Handling of Case Sensitivity, with related authorization failures covered by CWE-863 and CWE-636.
Potential impact
- An authenticated user may access an application excluded by per-app user, group, OAuth, LDAP, or IP restrictions
- Authorization boundaries between applications could be weakened
- Restricted application content or functionality could be exposed
- Audit records may show an authenticated request without clearly indicating the policy lookup mismatch
General mitigation guidance
Mitigation generally focuses on consistent canonicalization and fail-closed authorization behavior.
Common defensive patterns include:
- Normalize hostnames using a single, standards-aligned representation before comparison
- Apply identical canonicalization to configured values, forwarded values, static ACL keys, and Docker labels
- Treat missing or ambiguous application-policy lookups as denied or configuration errors
- Validate trusted proxy headers and restrict which proxies may provide them
- Keep per-application authorization checks independent from authentication success
- Run services with least privilege so an authorization mistake limits exposure
How teams detect issues like this
Detection approaches can include:
- Static analysis rules that identify case-sensitive comparisons of hostnames or other canonicalizable identifiers
- Code review checks for authorization decisions based on raw forwarded headers
- Tests using equivalent hostname variants, including mixed-case values, across every ACL lookup path
- Integration tests that verify unmatched policy lookups fail closed
- Monitoring for requests whose forwarded host casing differs from configured application identifiers
- Policy enforcement requiring normalization and explicit deny behavior for missing access-control records

