When using SSL/TLS with Jetty, either with HTTP/1.1, HTTP/2, or WebSocket, the server may receive an invalid large (greater than 17408) TLS frame that is incorrectly handled, causing CPU resources to eventually reach 100% usage.
package org.eclipse.jetty.server.ssl.fix6072;
import java.nio.ByteBuffer;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.ssl.SslContextFactory;
public class SpaceCheckingSslConnectionFactory extends SslConnectionFactory
{
public SpaceCheckingSslConnectionFactory(@Name("sslContextFactory") SslContextFactory factory, @Name("next") String nextProtocol)
{
super(factory, nextProtocol);
}
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected SSLEngineResult unwrap(SSLEngine sslEngine, ByteBuffer input, ByteBuffer output) throws SSLException
{
SSLEngineResult results = super.unwrap(sslEngine, input, output);
if ((results.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW ||
results.getStatus() == SSLEngineResult.Status.OK && results.bytesConsumed() == 0 && results.bytesProduced() == 0) &&
BufferUtil.space(input) == 0)
{
BufferUtil.clear(input);
throw new SSLHandshakeException("Encrypted buffer max length exceeded");
}
return results;
}
};
}
}
<Call name="addIfAbsentConnectionFactory">
<Arg>
<New class="org.eclipse.jetty.server.ssl.fix6072.SpaceCheckingSslConnectionFactory">
<Arg name="next">http/1.1</Arg>
<Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
</New>
</Arg>
</Call>
Impact
When using SSL/TLS with Jetty, either with HTTP/1.1, HTTP/2, or WebSocket, the server may receive an invalid large (greater than 17408) TLS frame that is incorrectly handled, causing CPU resources to eventually reach 100% usage.
Workarounds
The problem can be worked around by compiling the following class:
This class can be deployed by:
${jetty.home}/modules/ssl.mod
to${jetty.base}/modules
${jetty.base}/modules/ssl.mod
file to have the following section:${jetty.home}/etc/jetty-https.xml
and${jetty.home}/etc/jetty-http2.xml
to${jetty.base}/etc
${jetty.base}/etc/jetty-https.xml
and${jetty.base}/etc/jetty-http2.xml
, changing any reference oforg.eclipse.jetty.server.SslConnectionFactory
toorg.eclipse.jetty.server.ssl.fix6072.SpaceCheckingSslConnectionFactory
. For example:References