Uploaded image for project: 'Undertow'
  1. Undertow
  2. UNDERTOW-835

CVE-2016-7046: Long URL proxy request lead to java.nio.BufferOverflowException and DoS

XMLWordPrintable

      Hi everyone,
      I've configured wildfly 10.1.0/undertow 1.4.0 to act as reverse proxy server, default buffer sizes used. When a GET request with veeeery long URL (about 1900 characters) is sent, the proxy server

      • return error 500 (that's ok)
      • starts to consume 100% CPU
      • starts to fill logs log file with exceptions very fast (so disk space gets exhausted quickly)
        E.g. some infinite loop is initiated by the request. Proxy server must be restarted to stop the problem.

      First exception printed is:

      ERROR [io.undertow.request] (default I/O-7) UT005071: Undertow request failed HttpServerExchange{ GET /obelisk-gui/ request {Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8], Accept-Language=[cs,en-US;q=0.7,en;q=0.3], Accept-Encoding=[gzip, deflate], DNT=[1], User-Agent=[Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0], Connection=[keep-alive], Cookie=[JSESSIONID=xxxx], Referer=[xxx], Upgrade-Insecure-Requests=[1], Host=[localhost]} response {}}: java.nio.BufferOverflowException
        at java.nio.Buffer.nextPutIndex(Buffer.java:521)
        at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:169)
        at io.undertow.client.http.HttpRequestConduit.processWrite(HttpRequestConduit.java:136)
        at io.undertow.client.http.HttpRequestConduit.flush(HttpRequestConduit.java:573)
        at io.undertow.conduits.AbstractFixedLengthStreamSinkConduit.flush(AbstractFixedLengthStreamSinkConduit.java:229)
        at org.xnio.conduits.ConduitStreamSinkChannel.flush(ConduitStreamSinkChannel.java:162)
        at io.undertow.client.http.HttpClientConnection.initiateRequest(HttpClientConnection.java:403)
        at io.undertow.client.http.HttpClientConnection.sendRequest(HttpClientConnection.java:331)
        at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction.run(ProxyHandler.java:502)
        at io.undertow.util.SameThreadExecutor.execute(SameThreadExecutor.java:35)
        at io.undertow.server.HttpServerExchange.dispatch(HttpServerExchange.java:790)
        at io.undertow.server.handlers.proxy.ProxyHandler$ProxyClientHandler.completed(ProxyHandler.java:284)
        at io.undertow.server.handlers.proxy.ProxyHandler$ProxyClientHandler.completed(ProxyHandler.java:260)
        at io.undertow.server.handlers.proxy.ProxyConnectionPool.connectionReady(ProxyConnectionPool.java:325)
        at io.undertow.server.handlers.proxy.ProxyConnectionPool.connect(ProxyConnectionPool.java:512)
        at io.undertow.server.handlers.proxy.LoadBalancingProxyClient.getConnection(LoadBalancingProxyClient.java:301)
        at io.undertow.server.handlers.proxy.ProxyHandler$ProxyClientHandler.run(ProxyHandler.java:278)
        at io.undertow.util.SameThreadExecutor.execute(SameThreadExecutor.java:35)
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:218)
        at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:243)
        at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:134)
        at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:58)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
        at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
        at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
        at org.xnio.nio.WorkerThread.run(WorkerThread.java:567)
      

      (the client gots the err 500 response at this point)

      And all the next exceptions in the log are:

      ERROR [org.xnio.listener] (default I/O-7) XNIO001007: A channel event listener threw an exception: java.nio.BufferOverflowException
        at java.nio.Buffer.nextPutIndex(Buffer.java:521)
        at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:169)
        at io.undertow.client.http.HttpRequestConduit.processWrite(HttpRequestConduit.java:136)
        at io.undertow.client.http.HttpRequestConduit.flush(HttpRequestConduit.java:573)
        at io.undertow.conduits.AbstractFixedLengthStreamSinkConduit.flush(AbstractFixedLengthStreamSinkConduit.java:229)
        at org.xnio.conduits.ConduitStreamSinkChannel.flush(ConduitStreamSinkChannel.java:162)
        at io.undertow.channels.DetachableStreamSinkChannel.flush(DetachableStreamSinkChannel.java:119)
        at io.undertow.server.handlers.proxy.ProxyHandler$HTTPTrailerChannelListener.handleEvent(ProxyHandler.java:681)
        at io.undertow.server.handlers.proxy.ProxyHandler$HTTPTrailerChannelListener.handleEvent(ProxyHandler.java:663)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
        at io.undertow.channels.DetachableStreamSinkChannel$SetterDelegatingListener.handleEvent(DetachableStreamSinkChannel.java:285)
        at io.undertow.channels.DetachableStreamSinkChannel$SetterDelegatingListener.handleEvent(DetachableStreamSinkChannel.java:272)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
        at org.xnio.conduits.WriteReadyHandler$ChannelListenerHandler.writeReady(WriteReadyHandler.java:65)
        at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:94)
        at org.xnio.nio.WorkerThread.run(WorkerThread.java:567)
      

      I suppose that the first exception is ok, the others (infinite loop) are not and should be fixed. (Or url length can be checked to the buffer size before proxying the request).

      Increasing buffer size resolved the problem, however, request of any length of the url can arrive.

      David

              sdouglas1@redhat.com Stuart Douglas (Inactive)
              david.klika David Klika (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: