Rack::Request parses the Host header using an AUTHORITY regular expression that accepts characters not permitted in RFC-compliant hostnames, including /, ?, #, and @. Because req.host returns the full parsed value, applications that validate hosts using naive prefix or suffix checks can be bypassed.
For example, a check such as req.host.start_with?("myapp.com") can be bypassed with Host: myapp.com@evil.com, and a check such as req.host.end_with?("myapp.com") can be bypassed with Host: evil.com/myapp.com.
This can lead to host header poisoning in applications that use req.host, req.url, or req.base_url for link generation, redirects, or origin validation.
Rack::Request parses the authority component using logic equivalent to:
AUTHORITY = /
\A
(?<host>
\[(?<address>#{ipv6})\]
|
(?<address>[[[:graph:]&&[^\[\]]]]*?)
)
(:(?<port>\d+))?
\z
/x
The character class used for non-IPv6 hosts accepts nearly all printable characters except [ and ]. This includes reserved URI delimiters such as @, /, ?, and #, which are not valid hostname characters under RFC 3986 host syntax.
As a result, values such as the following are accepted and returned through req.host:
myapp.com@evil.com
evil.com/myapp.com
evil.com#myapp.com
Applications that attempt to allowlist hosts using string prefix or suffix checks may therefore treat attacker-controlled hosts as trusted. For example:
req.host.start_with?("myapp.com")
accepts:
myapp.com@evil.com
and:
req.host.end_with?("myapp.com")
accepts:
evil.com/myapp.com
When those values are later used to build absolute URLs or enforce origin restrictions, the application may produce attacker-controlled results.
Applications that rely on req.host, req.url, or req.base_url may be affected if they perform naive host validation or assume Rack only returns RFC-valid...
3.1.213.2.6Exploitability
AV:NAC:HPR:NUI:NScope
S:UImpact
C:LI:LA:N4.8/CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N