我有一个 Apache/2.4.6 (CentOS) 服务器,其中有多个子域作为 Apache VirtualHost 中的 ServerAlias。
类似于:
<VirtualHost *:443>
ServerName mydomain.com
ServerAlias a.mydomain.com
ServerAlias b.mydomain.com
每个客户公司都应通过其子域进行访问,并且为了安全起见,每个客户公司都有不同的数据库,数据是分离的。
一位网络安全专家提醒我,存在一个漏洞,一个子域“a.mydomain.com”的用户可以通过在从客户端到 Web 服务器的调用中添加 Host 标头来访问另一个子域“b.mydomain.com”。
一开始我尝试用 PHP 获取信息,但失败了,PHP 没有获取到 headers 信息。然后我转而寻找在 Web 服务器级别(Apache)上解决此问题的方法。
当恶意用户试图欺骗服务器并使用主机头将请求发送到另一个子域时,我想要检测并拒绝,在此示例中,用户应该由 a.mydomain.com 而不是 b.mydomain.com 提供服务:
curl 'https://a.mydomain.com/users/login' \
-H 'Host: b.mydomain.com' \
--data-raw $'{"email":"[email protected]","password":"*****"}'
来自客户端应用程序的正常调用如下所示:
curl 'https://a.mydomain.com/users/login' \
--data-raw $'{"email":"[email protected]","password":"*****"}'
我尝试过RequestHeader unset host
,但是它并没有像我预期的那样工作。
我的预期是,如果恶意用户发送了“Host”标头,服务器应该会忽略它。这将导致上述两个 culr 调用实际上相同。
我认为发生的情况是 Apache 在调用中使用了 URL,但是如果存在“Host”标头,则它将优先使用并且使用该标头,而 URL 中的原始域将被丢弃。
如果是这种情况,则RequestHeader unset host
不会向我的 PHP 代码发送任何主机,这会导致我的代码中断,因为它需要知道哪个客户公司正在调用它。