Skip to content

Commit fd69798

Browse files
committed
Let the HTTP/2 max number of small continuation frames allowed to be configuration.
Motivation: Netty has a protection against a Zero-Byte Frame Bypass attack, that allows 16 frames by default. We should make this setting configurable.
1 parent f95856c commit fd69798

3 files changed

Lines changed: 38 additions & 0 deletions

File tree

src/main/java/io/vertx/core/http/HttpServerOptions.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ public class HttpServerOptions extends NetServerOptions {
201201
*/
202202
public static final TimeUnit DEFAULT_HTTP2_RST_FLOOD_WINDOW_DURATION_TIME_UNIT = TimeUnit.SECONDS;
203203

204+
/**
205+
* HTTP/2 maximum allowed number of small continuation frames.
206+
*/
207+
public static final int DEFAULT_HTTP2_MAX_SMALL_CONTINUATION_FRAMES = 16;
208+
204209
private boolean compressionSupported;
205210
private int compressionLevel;
206211
private List<CompressionOptions> compressors;
@@ -231,6 +236,7 @@ public class HttpServerOptions extends NetServerOptions {
231236
private boolean registerWebSocketWriteHandlers;
232237
private int http2RstFloodMaxRstFramePerWindow;
233238
private int http2RstFloodWindowDuration;
239+
private int http2MaxSmallContinuationFrames;
234240
private TimeUnit http2RstFloodWindowDurationTimeUnit;
235241

236242
/**
@@ -280,6 +286,7 @@ public HttpServerOptions(HttpServerOptions other) {
280286
this.http2RstFloodMaxRstFramePerWindow = other.http2RstFloodMaxRstFramePerWindow;
281287
this.http2RstFloodWindowDuration = other.http2RstFloodWindowDuration;
282288
this.http2RstFloodWindowDurationTimeUnit = other.http2RstFloodWindowDurationTimeUnit;
289+
this.http2MaxSmallContinuationFrames = other.http2MaxSmallContinuationFrames;
283290
}
284291

285292
/**
@@ -335,6 +342,7 @@ private void init() {
335342
http2RstFloodMaxRstFramePerWindow = DEFAULT_HTTP2_RST_FLOOD_MAX_RST_FRAME_PER_WINDOW;
336343
http2RstFloodWindowDuration = DEFAULT_HTTP2_RST_FLOOD_WINDOW_DURATION;
337344
http2RstFloodWindowDurationTimeUnit = DEFAULT_HTTP2_RST_FLOOD_WINDOW_DURATION_TIME_UNIT;
345+
http2MaxSmallContinuationFrames = DEFAULT_HTTP2_MAX_SMALL_CONTINUATION_FRAMES;
338346
}
339347

340348
@Override
@@ -1274,4 +1282,27 @@ public HttpServerOptions setHttp2RstFloodWindowDurationTimeUnit(TimeUnit http2Rs
12741282
this.http2RstFloodWindowDurationTimeUnit = http2RstFloodWindowDurationTimeUnit;
12751283
return this;
12761284
}
1285+
1286+
/**
1287+
* @return the max number of small continuation frame allowed
1288+
*/
1289+
public int getHttp2MaxSmallContinuationFrames() {
1290+
return http2MaxSmallContinuationFrames;
1291+
}
1292+
1293+
/**
1294+
* Set the maximum number of small continuation frames allowed, this is used to prevent flood DoS attack
1295+
* via <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-33871">zero-byte continuation frames</a>. The default value
1296+
* is {@link #DEFAULT_HTTP2_MAX_SMALL_CONTINUATION_FRAMES}.
1297+
*
1298+
* @param http2MaxSmallContinuationFrames the max number of small continuation frame allowed
1299+
* @return a reference to this, so the API can be used fluently
1300+
*/
1301+
public HttpServerOptions setHttp2MaxSmallContinuationFrames(int http2MaxSmallContinuationFrames) {
1302+
if (http2MaxSmallContinuationFrames < 1) {
1303+
throw new IllegalArgumentException();
1304+
}
1305+
this.http2MaxSmallContinuationFrames = http2MaxSmallContinuationFrames;
1306+
return this;
1307+
}
12771308
}

src/main/java/io/vertx/core/http/impl/HttpServerWorker.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,11 @@ VertxHttp2ConnectionHandler<Http2ServerConnection> buildHttp2ConnectionHandler(C
253253
HttpServerMetrics metrics = (HttpServerMetrics) server.getMetrics();
254254
int maxRstFramesPerWindow = options.getHttp2RstFloodMaxRstFramePerWindow();
255255
int secondsPerWindow = (int)options.getHttp2RstFloodWindowDurationTimeUnit().toSeconds(options.getHttp2RstFloodWindowDuration());
256+
int maxSmallContinuationFrames = options.getHttp2MaxSmallContinuationFrames();
256257
VertxHttp2ConnectionHandler<Http2ServerConnection> handler = new VertxHttp2ConnectionHandlerBuilder<Http2ServerConnection>()
257258
.server(true)
258259
.useCompression(compressionOptions)
260+
.decoderEnforceMaxSmallContinuationFrames(maxSmallContinuationFrames)
259261
.decoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow)
260262
.encoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow)
261263
.useDecompression(options.isDecompressionSupported())

src/main/java/io/vertx/core/http/impl/VertxHttp2ConnectionHandlerBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ VertxHttp2ConnectionHandlerBuilder<C> useUniformStreamByteDistributor(boolean us
5858
return this;
5959
}
6060

61+
@Override
62+
protected VertxHttp2ConnectionHandlerBuilder<C> decoderEnforceMaxSmallContinuationFrames(int maxSmallContinuationFrames) {
63+
return super.decoderEnforceMaxSmallContinuationFrames(maxSmallContinuationFrames);
64+
}
65+
6166
@Override
6267
protected VertxHttp2ConnectionHandlerBuilder<C> decoderEnforceMaxRstFramesPerWindow(int maxRstFramesPerWindow, int secondsPerWindow) {
6368
return super.decoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow);

0 commit comments

Comments
 (0)