Rack::Sendfile#map_accel_path interpolates the value of the X-Accel-Mapping request header directly into a regular expression when rewriting file paths for X-Accel-Redirect. Because the header value is not escaped, an attacker who can supply X-Accel-Mapping to the backend can inject regex metacharacters and control the generated X-Accel-Redirect response header.
In deployments using Rack::Sendfile with x-accel-redirect, this can allow an attacker to cause nginx to serve unintended files from configured internal locations.
Rack::Sendfile#map_accel_path processes header-supplied mappings using logic equivalent to:
mapping.split(',').map(&:strip).each do |m|
internal, external = m.split('=', 2).map(&:strip)
new_path = path.sub(/\A#{internal}/i, external)
return new_path unless path == new_path
end
Here, internal comes from the HTTP_X_ACCEL_MAPPING request header and is inserted directly into a regular expression without escaping. This gives the header value regex semantics rather than treating it as a literal prefix.
As a result, an attacker can supply metacharacters such as .* or capture groups to alter how the path substitution is performed. For example, a mapping such as:
X-Accel-Mapping: .*=/protected/secret.txt
causes the entire source path to match and rewrites the redirect target to a clean attacker-chosen internal path.
This differs from the documented behavior of the header-based mapping path, which is described as a simple substitution. While application-supplied mappings may intentionally support regular expressions, header-supplied mappings should be treated as literal path prefixes.
The issue is only exploitable when untrusted X-Accel-Mapping headers can reach Rack. One realistic case is a reverse proxy configuration that intends to set X-Accel-Mapping itself, but fails to do so on some routes, allowing a client-supplied header to pass through unchanged.
2.2.233.1.213.2.6Exploitability
AV:NAC:HPR:NUI:NScope
S:UImpact
C:HI:NA:N5.9/CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N