Non-standard HTTP headers 'X-Forwarded-Host' 等出现在 HTTP 响应中

Non-standard HTTP headers 'X-Forwarded-Host' etc appear in the HTTP response

我们在 AWS 上部署了一个应用程序。在前面,AWS 负载均衡器接受所有传入的 HTTP 请求; EC2 实例直接位于该平衡器之后。在单个实例上,HAproxy 接收所有请求并根据 Java 委托给真正的应用服务器(在我们的特殊情况下,haproxy 和业务应用服务器在同一个 EC2 实例上,haproxy 不发挥负载平衡roles只是为了中继http请求,换句话说,haproxy和应用服务器是one-to-one映射。

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

请求

GET /token HTTP/1.1
Host: xxx.xxx.xxx.xxx

回应

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 

据我了解,X-Forwarded-* 应该只出现在服务器端,以便服务器在有代理时识别传入请求的来源in-between。我不知道为什么那些 headers 也出现在响应中。这让我担心将内部 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 }

请告知为什么那些 non-standard headers 出现在 http 响应中,以及这是否对安全有风险。

AWS ELB 根据 AWS ELB docs 自动添加 X-Forwarded-ForX-Forwarded-PortX-Forwarded-Proto 请求 header;他们使用X-Forwarded-Hostheader。因此,您的 haproxy 配置中的这条规则有点可疑:

acl forwarded hdr_cnt(X-Forwarded-Host) gt 0

相反,您可以尝试:

acl forwarded hdr_cnt(X-Forwarded-For) gt 0

X-Forwarded-Host请求header比较不寻常;除非你的后端服务器(WS02,从外观上看)需要 header,你可以删除它,以及你的 haproxy 中的其他 X-Forwarded-* 规则] 一起配置,因为这些值应该来自 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 }

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

因此,当你研究这个时,你可以 haproxy 删除这些响应 headers,使用类似的东西:

rspdel ^X-Forwarded-.*:.*

希望对您有所帮助!