如何在存在主机 header 时确定请求的真实服务器端口
How to determine a request's real serverPort when a Host header is present
我有一个启用了管理端点的 spring 启动应用程序。
这意味着应用程序在端口 8080 上启动,管理端点在端口 8081 上可用。
该应用程序使用 spring 安全性进行保护,但是,无需身份验证即可访问管理端点。所以我添加了一个请求匹配器来评估服务器端口(使用 request.getServerPort()
)以忽略对端口 8081 上的管理端点的所有请求。
现在碰巧当 Host
header 存在时,header 的端口在 request.getServerPort()
中返回,而不是真正的服务器端口。
这意味着我可以使用带有端口 8081 的 Host
header 访问应用程序并绕过 Spring 安全!?
为了清楚起见,示例:
curl localhost:8080
returns 401 (unauthorized, that's correct)
curl localhost:8081/health
returns 200 (found)
但是
curl -H "Host: localhost:8081" localhost:8080
returns 200 (wtf?) - because request.getServerPort() == 8081
curl -H "Host: localhost:8080" localhost:8081/health
returns 401 - because request.getServerPort() == 8080
问题是:如何确定应用程序接收请求的真实端口?
ServletRequest#getLocalName() returns local hostname.
ServletRequest#getLocalAddr() returns local IP.
ServletRequest#getLocalPort() returns local port.
为了更清楚,请参考:
Get Application Server name or ip and port in Java
我有一个启用了管理端点的 spring 启动应用程序。 这意味着应用程序在端口 8080 上启动,管理端点在端口 8081 上可用。
该应用程序使用 spring 安全性进行保护,但是,无需身份验证即可访问管理端点。所以我添加了一个请求匹配器来评估服务器端口(使用 request.getServerPort()
)以忽略对端口 8081 上的管理端点的所有请求。
现在碰巧当 Host
header 存在时,header 的端口在 request.getServerPort()
中返回,而不是真正的服务器端口。
这意味着我可以使用带有端口 8081 的 Host
header 访问应用程序并绕过 Spring 安全!?
为了清楚起见,示例:
curl localhost:8080
returns 401 (unauthorized, that's correct)
curl localhost:8081/health
returns 200 (found)
但是
curl -H "Host: localhost:8081" localhost:8080
returns 200 (wtf?) - because request.getServerPort() == 8081
curl -H "Host: localhost:8080" localhost:8081/health
returns 401 - because request.getServerPort() == 8080
问题是:如何确定应用程序接收请求的真实端口?
ServletRequest#getLocalName() returns local hostname.
ServletRequest#getLocalAddr() returns local IP.
ServletRequest#getLocalPort() returns local port.
为了更清楚,请参考: Get Application Server name or ip and port in Java