ServletUtils.createHTTPRequest() issue with IPv6

Issue #376 resolved
Henri Mikkonen created an issue

I’ve been using the following logic for quite some time to build HTTPRequest object from HttpServletRequest:

HTTPRequest httpReq = ServletUtils.createHTTPRequest(httpServletRequest);

After upgrading the servlet container (Jetty) to a newer version, the same logic doesn’t work anymore with IPv6. The stack trace is the following:

java.lang.IllegalArgumentException: Invalid request URL: Invalid host: [[xxxx:xxx:xx:xxx:x:x:xxx:x]: https://[[xxxx:xxx:xx:xxx:x:x:xxx:x]]/...
        at com.nimbusds.oauth2.sdk.http.ServletUtils.createHTTPRequest(ServletUtils.java:172)
Caused by: java.net.MalformedURLException: Invalid host: [[xxxx:xxx:xx:xxx:x:x:xxx:x]
        at java.base/java.net.URL.<init>(URL.java:679)
Caused by: java.lang.IllegalArgumentException: Invalid host: [[xxxx:xxx:xx:xxx:x:x:xxx:x]
        at java.base/java.net.URLStreamHandler.parseURL(URLStreamHandler.java:195)

The reason for the error seems to be the double brackets in the host address. The method reconstructRequestURLString in ServletUtils seems to always add brackets to the IPv6 address, without checking the if they might have already existed:

        String localAddress = request.getLocalAddr();

        if (localAddress == null || localAddress.trim().isEmpty()) {
            // Unknown local address (hostname / IP address)
        } else if (localAddress.contains(".")) {
            // IPv3 address
            sb.append(localAddress);
        } else if (localAddress.contains(":")) {
            // IPv6 address, see RFC 2732
            sb.append('[');
            sb.append(localAddress);
            sb.append(']');
        }

I suspect that the newer version of Jetty is returning the IPv6 address with brackets via request.getLocalAddr() , as the older version probably didn’t (?) It’s not clear to me if this code should check if the brackets already existed instead of just adding them in any case? Or is it a bug on Jetty -side to include the brackets nowadays?

With Jetty 9.4.30.v20200611 it was working, but with Jetty 9.4.43.v20210629 I get the error.

Comments (4)

  1. Yavor Vasilev

    Hi Henri,

    This looks like a bug in the getLocalAddr implementation. In a pure IPv6 address there must be not enclosing brackets. Only when the IPv6 address is in a URL. I suspect the Jetty parsing of the host component from a URL got bugged.

    https://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getLocalAddr()

    https://datatracker.ietf.org/doc/html/rfc2732#section-2

    I’d suggest to report this bug with Jetty. But it may take time for them until this gets resolved. I’ll try to work around this later next week. If you have the time and resources to take care of that before just file a PR and we’ll release it immediately.

  2. Henri Mikkonen reporter

    Hi Yavor,

    I completely agree with your analysis regarding Jetty’s implementation for getLocalAddr(). However, after reading various threads regarding IPv6 addresses in Jetty, they seem to quite convinced themselves that it's not wrong to include brackets in the address, even though when it's not related to URL. So it'd be excellent if Nimbus was updated to handle the existing brackets.

    Also, at least from our perspective, I don’t see a reason why this ServletUtils.createHTTPRequest() is building the URL with the local IP address? Is it perhaps needed only in some special cases? Could it be avoided with a flag in the method parameters?

  3. Yavor Vasilev
    • changed status to open

    Thanks for reporting the Jetty situation. I'm going to add a workaround. It feels simpler than updating the API with a new flag to ignore the IP address. Besides, some people may get an unexpected exception if they are not prepared for that.

  4. Log in to comment