This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 2b4cd683940e63d7d1e61677e9edba18a333c1e7
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 dacc2392ad..d8fb3f400c 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;
@@ -61,11 +63,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;
@@ -287,9 +297,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 a4161d4ec4..6f26029d0f 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

Reply via email to