ServletUtils.createHTTPRequest() issue with IPv6
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)
-
-
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? -
- 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.
-
- changed status to resolved
Fixed in this commit: 8c00338e
(hope no further issues with Jetty :))
- Log in to comment
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.