非标准 HTTP 标头“X-Forwarded-Host”等出现在 HTTP 响应中

Bo *_* Ye 2 haproxy amazon-web-services x-forwarded-for

我们在AWS上部署了一个应用程序。在前面,AWS 负载均衡器接受所有传入的 HTTP 请求;EC2 实例直接位于该平衡器后面。在单个实例上,HAproxy 接收所有请求,然后委托给基于 Java 的真实应用程序服务器(在我们的特殊情况下,haproxy 和业务应用程序服务器位于同一个 EC2 实例上,haproxy 不扮演负载平衡角色,仅用于中继http请求,也就是说haproxy和应用服务器是一一映射的)。

当我们尝试启动对此系统的 http 调用时:

要求

GET /token HTTP/1.1
Host: xxx.xxx.xxx.xxx
Run Code Online (Sandbox Code Playgroud)

回复

HTTP/1.1 403 Forbidden 
X-Forwarded-Proto: https 
X-Forwarded-For: xxx.xxx.xxx.xxx 
X-Forwarded-Port: 443 
X-Forwarded-Host: xx.xx.xx.xxx 
Date: Wed, 09 Dec 2015 22:04:06 GMT 
Server: WSO2-PassThrough-HTTP 
Run Code Online (Sandbox Code Playgroud)

根据我的理解,X-Forwarded-*应该只出现在服务器端,以便服务器在中间有代理时识别传入请求的来源。我不知道为什么这些标题也出现在响应中。这让我担心内部 IP 会泄露给潜在的恶意客户端。

以下是haproxy设置的代码片段:

frontend worker
bind :443 ssl crt xxx crt xxx crt xx accept-proxy no-sslv3 no-tls-tickets
mode http
acl forwarded hdr_cnt(X-Forwarded-Host) gt 0
acl trusted src 127.0.0.0/24
capture request header X-Forwarded-For len 64
default_backend worker
http-request deny if METH_TRACE
http-request set-header X-Forwarded-Host %[dst] unless forwarded trusted
http-request set-header X-Forwarded-Port %[dst_port]
http-request set-header X-Forwarded-Proto https if { ssl_fc }
option forwardfor if-none
reqidel ^X-Forwarded-For:.* unless trusted
rspadd Strict-Transport-Security:\ max-age=63072000;\ includeSubdomains;\ preload
use_backend xxx.xxx.xxx if { ssl_fc_sni -i xxx.xxx.xxx }
use_backend xxx.xxx.xxx if { ssl_fc_sni -i xxx.xxx.xxx }
Run Code Online (Sandbox Code Playgroud)

请告知为什么这些非标准标头出现在 http 响应中以及这是否存在安全风险。

Cas*_*lia 6

根据AWS ELB 文档, AWS ELB 自动添加X-Forwarded-ForX-Forwarded-Port和请求标头;他们不使用标题。因此,您的配置中的这条规则有点可疑:X-Forwarded-ProtoX-Forwarded-Hosthaproxy

acl forwarded hdr_cnt(X-Forwarded-Host) gt 0
Run Code Online (Sandbox Code Playgroud)

相反,您可以尝试:

acl forwarded hdr_cnt(X-Forwarded-For) gt 0
Run Code Online (Sandbox Code Playgroud)

请求X-Forwarded-Host头比较不常见;除非您的后端服务器(从外观上看是 WS02)需要该标头,否则您可以X-Forwarded-*从配置中完全删除该标头以及其他规则haproxy,因为这些值应该来自 AWS ELB。也就是说,您可以完全删除这些:

http-request set-header X-Forwarded-Host %[dst] unless forwarded trusted
http-request set-header X-Forwarded-Port %[dst_port]
http-request set-header X-Forwarded-Proto https if { ssl_fc }
Run Code Online (Sandbox Code Playgroud)

至于是否存在安全问题——仅针对 HTTP 请求,而不是HTTPS 请求。这只是因为,如果没有 SSL,某人就有可能拦截和窃听这些响应标头。这样的攻击者已经知道客户端的 IP 地址(因此知道 的值X-Forwarded-For),知道 TCP 目标端口(因此知道 的值X-Forwarded-Port),并且知道它不是SSL(因此知道X-Forwarded-Proto: http)。但理想情况下,正如您所指出的,这些标头根本不会出现在响应中。(HTTP 服务器在响应中回显 此类请求标头的情况并不常见X-Forwarded-*;因此,我尝试阅读 WS02 文档,看看是否可以将其配置为执行类似的操作。)

因此,当您研究此问题时,您可以haproxy使用以下内容删除这些响应标头:

rspdel ^X-Forwarded-.*:.*
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!