Sinatra 4 and permitted_hosts config
Smart Proxy got support for Sinatra 4
Sinatra is a lightweight Ruby web framework used to build and run the Foreman Proxy.
PR #955 made it possible for Smart Proxy to use Sinatra 4 (and the required Rack 3).
It’s still possible to use Sinatra 2 (and the required Rack 2). When we migrate core Foreman to Sinatra 4, it will become the only supported option in Smart Proxy as well.
Sinatra 4 allows host authorization
Sinatra 4 adds an option to set :permitted_hosts. It is a list of hosts that the proxy “identifies as.” In other words, when a client makes a request, it needs to use a Host header matching one of the permitted_hosts; otherwise, it is rejected.
A request using the legitimate host is accepted:
curl https://smart-proxy-hostname.example.com/features
A request using a malicious host is rejected:
curl https://10.0.1.42/features --header 'Host: attack.example.com'
Note that this has nothing to do with the request’s origin and is unrelated to :trusted_hosts.
Why?
CVE-2024-21510 allows SSRF (server-side request forgery) by giving a server a fake hostname and making it consider its own.
Attack example: make a client access smart-proxy-hostname.example.com with an X-Forwarded-Host: attack.example.com header (for example, using JavaScript and a DNS rebinding attack). Smart Proxy trusts the header and redirects that request to attack.example.com, making the client actually connect to the attacker and bypass the same-origin policy.
How?
Set :permitted_hosts in Smart Proxy’s settings.yml.
foremanctl PR #900 allows foremanctl to configure Smart Proxy, and you can add more accepted hostnames using the --server-alias parameter.
Smart Proxy PR #960 makes Smart Proxy abide by that value.
An empty :permitted_hosts defaults to all hostnames being accepted. That means it’s backwards compatible. It also means that with an empty or unset :permitted_hosts, you don’t use the additional security Sinatra 4 provides.
Result
$ curl -k https://quadlet.example.com:8443/features
["logs","script"]
$ curl -k https://quadlet.example.com:8443/features -H "X-Forwarded-Host: attack.example.com"
Host not permitted
