Search code examples
javahttpurlencodespotbugs

fix for spot bug - HRS_REQUEST_PARAMETER_TO_HTTP_HEADER


I am executing below code inside servlet and getting this spot bugs - HRS_REQUEST_PARAMETER_TO_HTTP_HEADER Bug: HTTP parameter directly written to HTTP header output in SSOIdpLogoutRedirect.doPost(HttpServletRequest, HttpServletResponse)

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

To fix this bugs i added below code.

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

But URL does not redirect in correct way as i can see the relaystate url has been changed after encoding original relaystate = https://sad.ezhdj.net/system/web/apps/dfgh/ and after encoded it is

relaystate =https%3A%2F%2Fsad.ezdev.net%2Fsystem%2Fweb%2Fapps%2Fdfgh%2F`


Solution

  • you should use HttpServletResponse.encodeRedirectURL() to encode redirect urls:

    String encodeRedirectURL(String url)

    Encodes the specified URL for use in the sendRedirect method or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL.

    ...

    All URLs sent to the HttpServletResponse.sendRedirect method should be run through this method...

    this should work:

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

    since your url doesn't actually need encoding, output from encodeRedirectURL() will be:

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

    and the redirect will work just fine.

    edit:

    apparently proposed solution still triggers HRS_REQUEST_PARAMETER_TO_HTTP_HEADER spotbug error.

    after doing little more research I found out that the error is meant to prevent HTTP response splitting vulnerability (i.e. when unwanted \r\n are written in the header section of http response).

    we should then better sanitize relayState against this type of vulnerability.

    a simple relayState.replace("\r\n", "") is enough to make the error go away:

    response.sendRedirect(response.encodeRedirectURL(relayState.replace("\r\n", "")));