2

我在 servlet 中执行下面的代码并得到这个发现错误 - HRS_REQUEST_PARAMETER_TO_HTTP_HEADER 错误:HTTP 参数直接写入 SSOIdpLogoutRedirect.doPost(HttpServletRequest, HttpServletResponse) 中的 HTTP 标头输出

String relayState = request.getParameter("RELAY_STATE");
if(relayState != null)
{
 response.sendRedirect(relayState);
}

为了修复这个错误,我在下面添加了代码。

relayState = URLEncoder.encode(relayState,StandardCharsets.UTF_8);

但是 URL 没有以正确的方式重定向,因为我可以看到在对原始 relaystate = https://sad.ezhdj.net/system/web/apps/dfgh/进行编码后,relaystate url 已更改, 并且在编码后它是

中继状态=https%3A%2F%2Fsad.ezdev.net%2Fsystem%2Fweb%2Fapps%2Fdfgh%2F`

4

1 回答 1

2

您应该使用HttpServletResponse.encodeRedirectURL()编码重定向网址:

字符串 encodeRedirectURL(字符串 url)

对指定的 URL 进行编码以在sendRedirect方法中使用,或者,如果不需要编码,则返回未更改的 URL。此方法的实现包括确定是否需要在 URL 中编码会话 ID 的逻辑。

...

发送到该HttpServletResponse.sendRedirect方法的所有 URL 都应通过该方法运行...

这应该工作:

response.sendRedirect(response.encodeRedirectURL(relayState));

由于您的网址实际上不需要编码,因此输出encodeRedirectURL()将是:

https://sad.ezhdj.net/system/web/apps/dfgh/

并且重定向会正常工作。

编辑:

显然提出的解决方案仍然会触发HRS_REQUEST_PARAMETER_TO_HTTP_HEADERspotbug 错误。

在做了更多的研究之后,我发现该错误是为了防止HTTP 响应拆分漏洞(即当不需要\r\n的时候写入 HTTP 响应的标头部分)。

然后,我们应该更好地消除relayState这种类型的漏洞。

一个简单relayState.replace("\r\n", "")的就足以使错误消失:

response.sendRedirect(response.encodeRedirectURL(relayState.replace("\r\n", "")));
于 2020-11-22T10:38:33.307 回答