Apache is serving the first hosting account when specifying an arbitrary "Host" HTTP header not belonging to any account


Well-Known Member
Nov 3, 2016
Penarth, United Kingdom
cPanel Access Level
Root Administrator

I've noticed some unexpected behaviour regarding Apache on cPanel when manipulating the "Host" HTTP request header.

It would appear that if you perform a HTTP request to Apache when specifying an arbitrary hostname in the "Host" header of which does not match any domain names in any account, Apache will serve you the document root for the first hosting account alphabetically by primary domain name.

Example: You have a WHM server with the following accounts by primary domain name...
  • hellothere.net
  • myawesomewebsite.com
  • theia.org
Now lets put in a HTTP request with an arbitrary host header. Easily done with cURL:

curl --header "Host: www.example.com" "https://www.theia.org/"
What I'd expect to happen is Apache return a 404 error because no account exists claiming to own "www.example.com" (or "example.com"). Instead you'll be served the default web content for "hellothere.net", purely because that's the first account on this server alphabetically. That being said because HTTPS was used you'd really get an SNI error if your real URL request did not go to the first site, in this case "hellothere.net". Now let's try this request:

curl --header "Host: www.example.com" "https://www.hellothere.net/"
This will return content from that first hosting account's web content because there is no longer an SNI mismatch.

Is there a setting in WHM to adjust this behaviour, or is it a bug? (Or, hopefully not, the intended behaviour?)

This could technically be exploited as the website on that first account may make use of the HTTP host header for its dynamic route building of absolute URLs, which is common functionality on frameworks such as WordPress, Symfony, and Laravel. They would instead incorrectly use "www.example.com" instead of "www.theia.org" in dynamic HTML output, e.g. image URLs and script URLs because they need to use the HTTP host header for route building.


Product Owner II
Staff member
Nov 14, 2017
This is the standard behavior for Apache when making https requests. When a request is made over HTTPS like this and the domain does not exist but resolves to an IP on the server, Apache serves the first SSL VirtualHost in the configuration on that IP address. This is discussed in their documentation here: An In-Depth Discussion of Virtual Host Matching - Apache HTTP Server Version 2.4

Name-based vhost
If there are multiple VirtualHost directives listing the IP address and port combination that was determined to be the best match, the "list" in the remaining steps refers to the list of vhosts that matched, in the order they were in the configuration file.

If the connection is using SSL, the server supports Server Name Indication, and the SSL client handshake includes the TLS extension with the requested hostname, then that hostname is used below just like the Host: header would be used on a non-SSL connection. Otherwise, the first name-based vhost whose address matched is used for SSL connections. This is significant because the vhost determines which certificate the server will use for the connection.

If the request contains a Host: header field, the list is searched for the first vhost with a matching ServerName or ServerAlias, and the request is served from that vhost. A Host: header field can contain a port number, but Apache always ignores it and matches against the real port to which the client sent the request.

The first vhost in the config file with the specified IP address has the highest priority and catches any request to an unknown server name, or a request without a Host: header field (such as a HTTP/1.0 request).