有人设法将未定义的HTTP_HOST
服务器变量传递给我的应用程序脚本,从而触发了一系列错误。我非常不安,但无法复制此行为。我的 httpd 服务器使用基于名称的虚拟主机,其参数如下:
ServerName example.com:80
UseCanonicalName On
<VirtualHost *:80>
ServerName example.com
ServerAlias ftp.example.com service.example.com
ErrorDocument 404 /error/404.html.var
...
</VirtualHost>
<VirtualHost *:80>
ServerName notfound.example.com
ServerAlias *
RedirectMatch 404 ^/(?!error)
ErrorDocument 404 /error/404.html.var
</VirtualHost>
我尝试使用 wget 复制请求,如下所示:
wget -dS --header='Host: ' http://example.com/?x0a/x04/x0a/x04/x06/x08/x09/...
--2014-07-30 03:00:00-- http://example.com/?x0a/x04/x0a/x04/x06/x08/x09/...
Connecting to example.com:80... connected.
---request begin---
GET / HTTP/1.1
Accept: */*
Host:
Connection: Keep-Alive
---request end---
...
HTTP request sent, awaiting response...
---response begin--
HTTP/1.1 404 Not Found
Date: Wed, 29 Jul 2014 03:00:00 GMT
Server: Apache
Accept-Ranges: bytes
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Content-Language: en
---response end---
...
2014-07-29 03:00:00 ERROR 404: Not Found.
正如预期的那样,出现了 404 not found 错误。我想知道有人怎么能用未定义的 HTTP_HOST 触发 200 成功。Apache 中的 ServerAlias 是否完全依赖 HTTP_HOST?或者这可能是有人试图利用的服务器错误?
更新:
这是的输出httpd -S
:
VirtualHost configuration:
*:80 is a NameVirtualHost
default server example.com (/etc/httpd/conf/httpd.conf:410)
port 80 namevhost example.com (/etc/httpd/conf/httpd.conf:410)
alias localhost
alias xxx.xxx.xxx.xxx
alias ftp.example.com
alias service.example.com
port 80 namevhost notfound.example.com (/etc/httpd/conf/httpd.conf:491)
wild alias *
ServerRoot: "/etc/httpd"
Main DocumentRoot: "/var/www/html"
Main ErrorLog: "/etc/httpd/logs/error_log"
Mutex default: dir="/run/httpd/" mechanism=default
Mutex rewrite-map: using_defaults
Mutex ssl-stapling: using_defaults
Mutex proxy: using_defaults
Mutex ssl-cache: using_defaults
PidFile: "/run/httpd/httpd.pid"
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="apache" id=48 not_used
Group: name="apache" id=48 not_used
答案1
是的,ServerAlias 确实与HTTP_HOST
变量一起工作(更准确地说,与Host:
请求的 http 标头一起工作,它HTTP_HOST
也将被映射到)。
如果没有Host:
http 标头,并且 request_uri 也包含 http 主机(即GET http://example.com/path/to HTTP/1.1
),它也将被用作 HTTP_HOST。这通常仅在代理的情况下发生。
你的例子很糟糕,Host: 不能包含 url,只能包含主机名。如果有人在这里给出一个 url(可能是由一个糟糕的 http 工具提供的),它将被解释为无效/不存在的主机名,这就是你的情况。
实际上:虽然我可以找到并分析 apache 网络服务器(公共)源代码的相关部分,但我认为不需要这么困难的事情。你能做的最好的事情就是用一些telnet 127.0.0.1 80
或类似的命令来玩你自己的 apache。给你的虚拟主机 apache 提供不同的 GET /url、Host: 标头,看看会发生什么。当我需要调试虚拟主机 apache 配置时,我经常这样做。基于 telnet 的 http 查询 minimalexample 如下:
$ telnet 127.0.0.1 80
GET /test/url.html HTTP/1.1
Host: myapache.mydomain.com
Connection: close
(me: until this you need to type in, don't forget the multiple enter at the end)
200 HTTP/1.1 OK (<- me: from here is coming the reply of the server!)
Content-type: html/html
<html>
...
</html>