https://bz.apache.org/bugzilla/show_bug.cgi?id=70029
Bug ID: 70029
Summary: mod_cache should canonicalize Host/URI hostname
consistently when constructing cache keys
Product: Apache httpd-2
Version: 2.4.66
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: mod_cache
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
I found a cache-key consistency issue in Apache httpd mod_cache/mod_cache_disk
when used in a reverse-proxy configuration.
This was originally reported to [email protected]. Joe Orton reviewed it and
suggested filing it as a normal Bugzilla issue, noting that it is reasonable to
argue that the URI hostname should be canonicalised when constructing the cache
key.
In a configuration with mod_cache enabled on a proxied path, Apache appears to
fold/canonicalize some Host/authority variants for cache lookup, such as:
- example.com.
- EXAMPLE.COM
- example.com:80
to the canonical host example.com.
However, the backend can still receive the original raw Host/authority variant
through Host or X-Forwarded-Host, depending on ProxyPreserveHost and backend
behavior.
This means a backend response generated using the raw Host/X-Forwarded-Host
value can be stored under a cache key that is later reused for the canonical
host.
This is not HTTP/2-specific. I reproduced the same behavior using HTTP/1.1 Host
headers.
Minimal configuration:
CacheRoot /var/cache/apache2/h2cache
CacheDirLevels 2
CacheDirLength 2
CacheQuickHandler On
CacheHeader on
CacheLock On
CacheLockPath /tmp/mod_cache-lock
<VirtualHost 127.0.0.1:18080>
ServerName localhost
Protocols h2c http/1.1
ProxyPreserveHost On
CacheEnable disk "/proxy/"
RewriteEngine On
RewriteRule ^/proxy/(.*)$ http://127.0.0.1:9001/proxy/$1 [P,L]
</VirtualHost>
Backend behavior used for reproduction:
The backend generates a cacheable 302 redirect using the received Host header:
Location: http://<Host>/poisoned-by-<Host>/...
Cache-Control: public, max-age=600
Reproduction:
1. Clear mod_cache.
2. Seed cache using Host variant:
GET /proxy/redirect-test HTTP/1.1
Host: localhost.
Connection: close
Observed:
HTTP/1.1 302 Found
Location: http://localhost./poisoned-by-localhost./...
X-Cache: MISS from localhost
Backend received:
HOST=localhost.
XFH=localhost.
3. Request the same URI using canonical Host:
GET /proxy/redirect-test HTTP/1.1
Host: localhost
Connection: close
Observed:
HTTP/1.1 302 Found
Location: http://localhost./poisoned-by-localhost./...
X-Cache: HIT from localhost
The canonical Host request received the cached response generated for Host
localhost.
Observed result:
A response generated by the backend using Host localhost. is reused for Host
localhost.
Expected result:
Either:
- mod_cache should not fold Host variants that are forwarded raw to the
backend, or
- the cache key should reflect the raw Host/authority value that the backend
sees, or
- this behavior should be clearly documented as requiring Vary: Host for any
Host-dependent backend response.
Additional controls:
- The behavior is not HTTP/2-specific. The same issue was reproduced with
HTTP/1.1 Host headers.
- With Vary: Host returned by the backend, mod_cache correctly separates
localhost. and localhost:
- localhost. -> MISS
- localhost -> MISS
- localhost again -> HIT for localhost
- With ProxyPreserveHost Off, the backend may still receive the raw authority
through X-Forwarded-Host. If the backend uses X-Forwarded-Host to generate
public URLs, the same issue can occur.
Practical consequence:
In reverse-proxy deployments where backend responses are cacheable and depend
on Host or X-Forwarded-Host, this may cause cached response confusion across
Host variants, for example cached redirects or absolute links generated using a
trailing-dot, uppercase, or default-port Host variant.
I understand this may be configuration-dependent, but it seems the cache-key
construction and backend-visible authority normalization are inconsistent.
Environment:
Apache/2.4.66 (Debian)
Relevant modules:
- mod_cache
- mod_cache_disk
- mod_proxy
- mod_proxy_http
- mod_rewrite
- mod_headers
- mod_http2
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]