This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit a7697c9a2f0a0561f68bd713327f9d8f9080287a Author: Mark Thomas <ma...@apache.org> AuthorDate: Tue Aug 2 17:24:43 2022 +0100 Ensure HTTP/2 requests with connection specific headers are rejected. RFC 9113 explicitly lists the connection specific headers and we missed a few. --- java/org/apache/coyote/http2/LocalStrings.properties | 2 +- java/org/apache/coyote/http2/LocalStrings_fr.properties | 2 +- java/org/apache/coyote/http2/LocalStrings_ja.properties | 2 +- java/org/apache/coyote/http2/LocalStrings_ko.properties | 2 +- java/org/apache/coyote/http2/LocalStrings_zh_CN.properties | 2 +- java/org/apache/coyote/http2/Stream.java | 14 ++++++++++++-- webapps/docs/changelog.xml | 4 ++++ 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/java/org/apache/coyote/http2/LocalStrings.properties b/java/org/apache/coyote/http2/LocalStrings.properties index 6151d96924..823ea18a7c 100644 --- a/java/org/apache/coyote/http2/LocalStrings.properties +++ b/java/org/apache/coyote/http2/LocalStrings.properties @@ -86,7 +86,7 @@ pingManager.roundTripTime=Connection [{0}] Round trip time measured as [{1}]ns stream.clientCancel=Client reset the stream before the response was complete stream.closed=Connection [{0}], Stream [{1}], Unable to write to stream once it has been closed stream.header.case=Connection [{0}], Stream [{1}], HTTP header name [{2}] must be in lower case -stream.header.connection=Connection [{0}], Stream [{1}], HTTP header [connection] is not permitted in an HTTP/2 request +stream.header.connection=Connection [{0}], Stream [{1}], HTTP header [{2}] is not permitted in an HTTP/2 request stream.header.contentLength=Connection [{0}], Stream [{1}], The content length header value [{2}] does not agree with the size of the data received [{3}] stream.header.debug=Connection [{0}], Stream [{1}], HTTP header [{2}], Value [{3}] stream.header.duplicate=Connection [{0}], Stream [{1}], received multiple [{2}] headers diff --git a/java/org/apache/coyote/http2/LocalStrings_fr.properties b/java/org/apache/coyote/http2/LocalStrings_fr.properties index 5d2ac5e056..be7d040793 100644 --- a/java/org/apache/coyote/http2/LocalStrings_fr.properties +++ b/java/org/apache/coyote/http2/LocalStrings_fr.properties @@ -86,7 +86,7 @@ pingManager.roundTripTime=Connection [{0}] Le temps d''aller retour est de [{1}] stream.clientCancel=Le client a réinitialisé la stream avant que la réponse ne soit complète stream.closed=Connection [{0}], Flux [{1}], Impossible d''écrire sur un flux après sa fermeture stream.header.case=Connection [{0}], Flux [{1}], Le nom d''en-tête HTTP [{2}] doit être en miniscules -stream.header.connection=Connection [{0}], Flux [{1}], L''en-tête HTTP [connection] n''est pas autorisé dans une requête HTTP/2 +stream.header.connection=Connection [{0}], Flux [{1}], L''en-tête HTTP [{2}] n''est pas autorisé dans une requête HTTP/2 stream.header.contentLength=Connection [{0}], Flux [{1}], La valeur de l''en-tête content-length [{2}] ne correspond pas à la taille des données reçue [{3}] stream.header.debug=Connection [{0}], Flux [{1}], en-tête HTTP [{2}], valeur [{3}] stream.header.duplicate=Connection [{0}], Flux [{1}], Reçu plusieurs en-têtes [{2}] diff --git a/java/org/apache/coyote/http2/LocalStrings_ja.properties b/java/org/apache/coyote/http2/LocalStrings_ja.properties index 2f952d1f01..f4f7aa9b66 100644 --- a/java/org/apache/coyote/http2/LocalStrings_ja.properties +++ b/java/org/apache/coyote/http2/LocalStrings_ja.properties @@ -86,7 +86,7 @@ pingManager.roundTripTime=コネクション [{0}] の往復時間は [{1}] ns stream.clientCancel=レスポンスが完了する前にクライアントがストリームをリセットしました stream.closed=コネクション [{0}]、ストリーム [{1}]、切断したストリームには書き込みできません。 stream.header.case=コネクション [{0}]、ストリーム [{1}]、HTTP ヘッダー名 [{2}] は小文字でなければなりません。 -stream.header.connection=コネクション [{0}]、ストリーム [{1}]、HTTP/2 のリクエストには HTTP ヘッダー [connection] を指定することはできません。 +stream.header.connection=コネクション [{0}]、ストリーム [{1}]、HTTP/2 のリクエストには HTTP ヘッダー [{2}] を指定することはできません。 stream.header.contentLength=コネクション [{0}]、ストリーム [{1}]、content length ヘッダーの値 [{2}] と受信したデータ長 [{3}] は一致しません。 stream.header.debug=コネクション [{0}]、ストリーム [{1}]、HTTP ヘッダー [{2}]、値は [{3}] stream.header.duplicate=コネクション [{0}]、ストリーム [{1}]、ヘッダー [{2}] を複数受信しました。 diff --git a/java/org/apache/coyote/http2/LocalStrings_ko.properties b/java/org/apache/coyote/http2/LocalStrings_ko.properties index 180c595aa3..71433d9a00 100644 --- a/java/org/apache/coyote/http2/LocalStrings_ko.properties +++ b/java/org/apache/coyote/http2/LocalStrings_ko.properties @@ -86,7 +86,7 @@ pingManager.roundTripTime=연결 [{0}]: 라운드 트립 시간이 [{1}] 나노 stream.clientCancel=응답이 완료되기 전에 클라이언트가 스트림을 리셋했습니다. stream.closed=연결 [{0}], 스트림 [{1}], 한번 닫힌 스트림에 쓰기를 할 수 없습니다. stream.header.case=연결 [{0}], 스트림 [{1}], HTTP 헤더 이름 [{2}]은(는) 반드시 소문자여야 합니다. -stream.header.connection=연결 [{0}], 스트림 [{1}], HTTP 헤더 [connection]은 HTTP/2 요청에서 허용되지 않습니다. +stream.header.connection=연결 [{0}], 스트림 [{1}], HTTP 헤더 [{2}]은 HTTP/2 요청에서 허용되지 않습니다. stream.header.contentLength=연결 [{0}], 스트림 [{1}], 해당 Content-Length 헤더 값 [{2}]은(는) 수신된 데이터의 크기 [{3}]와(과) 일치하지 않습니다. stream.header.debug=연결 [{0}], 스트림 [{1}], HTTP 헤더: [{2}], 값: [{3}] stream.header.duplicate=연결 [{0}], 스트림 [{1}], 여러 개의 [{2}] 헤더들을 받았습니다. diff --git a/java/org/apache/coyote/http2/LocalStrings_zh_CN.properties b/java/org/apache/coyote/http2/LocalStrings_zh_CN.properties index af9bb0adc9..503e8a1105 100644 --- a/java/org/apache/coyote/http2/LocalStrings_zh_CN.properties +++ b/java/org/apache/coyote/http2/LocalStrings_zh_CN.properties @@ -86,7 +86,7 @@ pingManager.roundTripTime=连接[{0}]往返时间测量为[{1}]ns stream.clientCancel=客户端在响应完成前重置了数据流 stream.closed=连接[{0}],流[{1}],一旦关闭就无法写入流 stream.header.case=连接[{0}],流[{1}],HTTP标头名称[{2}]必须小写 -stream.header.connection=HTTP/2请求中不允许连接{0}、流{1}、HTTP头[连接] +stream.header.connection=HTTP/2请求中不允许连接{0}、流{1}、HTTP头[{2}] stream.header.contentLength=连接{0},流{1},内容长度头值{2}与接收的数据大小{3}不一致 stream.header.debug=连接[{0}],流[{1}],HTTP标头[{2}],值[{3}] stream.header.duplicate=连接[{0}],流[{1}],收到多个[{2}]头 diff --git a/java/org/apache/coyote/http2/Stream.java b/java/org/apache/coyote/http2/Stream.java index 0b25f6a942..fa78585a75 100644 --- a/java/org/apache/coyote/http2/Stream.java +++ b/java/org/apache/coyote/http2/Stream.java @@ -23,8 +23,10 @@ import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Collections; +import java.util.HashSet; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.function.Supplier; import org.apache.coyote.ActionCode; @@ -60,11 +62,19 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { private static final Integer HTTP_UPGRADE_STREAM = Integer.valueOf(1); + private static final Set<String> HTTP_CONNECTION_SPECIFC_HEADERS = new HashSet<>(); + static { Response response = new Response(); response.setStatus(100); StreamProcessor.prepareHeaders(null, response, true, null, null); ACK_HEADERS = response.getMimeHeaders(); + + HTTP_CONNECTION_SPECIFC_HEADERS.add("connection"); + HTTP_CONNECTION_SPECIFC_HEADERS.add("proxy-connection"); + HTTP_CONNECTION_SPECIFC_HEADERS.add("keep-alive"); + HTTP_CONNECTION_SPECIFC_HEADERS.add("transfer-encoding"); + HTTP_CONNECTION_SPECIFC_HEADERS.add("upgrade"); } private volatile long contentLengthReceived = 0; @@ -286,9 +296,9 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { getConnectionId(), getIdAsString(), name)); } - if ("connection".equals(name)) { + if (HTTP_CONNECTION_SPECIFC_HEADERS.contains(name)) { throw new HpackException(sm.getString("stream.header.connection", - getConnectionId(), getIdAsString())); + getConnectionId(), getIdAsString(), name)); } if ("te".equals(name)) { diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 79c8eebf2e..cb72bd83ea 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -131,6 +131,10 @@ Address an edge case in HTTP header parsing that allowed CRCRLF to be used as a valid line terminator. (markt) </fix> + <fix> + Ensure HTTP/2 requests that include connection specific headers are + rejected. (markt) + </fix> </changelog> </subsection> </section> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org