Re: Prague side meeting: HTTP/2 concurrency and request cancellation (CVE-2023-44487)
Willy Tarreau <w@1wt.eu> Wed, 11 October 2023 09:46 UTC
Return-Path: <ietf-http-wg-request+bounce-httpbisa-archive-bis2juki=ietf.org@listhub.w3.org>
X-Original-To: ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com
Delivered-To: ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id C1227C151545 for <ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com>; Wed, 11 Oct 2023 02:46:12 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -7.657
X-Spam-Level:
X-Spam-Status: No, score=-7.657 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, URIBL_DBL_BLOCKED_OPENDNS=0.001, URIBL_ZEN_BLOCKED_OPENDNS=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nbiBS6qhPhxa for <ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com>; Wed, 11 Oct 2023 02:46:07 -0700 (PDT)
Received: from lyra.w3.org (lyra.w3.org [128.30.52.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id A6C99C15109C for <httpbisa-archive-bis2Juki@ietf.org>; Wed, 11 Oct 2023 02:46:07 -0700 (PDT)
Received: from lists by lyra.w3.org with local (Exim 4.94.2) (envelope-from <ietf-http-wg-request@listhub.w3.org>) id 1qqVkC-000h6S-Vi for ietf-http-wg-dist@listhub.w3.org; Wed, 11 Oct 2023 09:43:08 +0000
Resent-Date: Wed, 11 Oct 2023 09:43:08 +0000
Resent-Message-Id: <E1qqVkC-000h6S-Vi@lyra.w3.org>
Received: from mimas.w3.org ([128.30.52.79]) by lyra.w3.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from <w@1wt.eu>) id 1qqVkB-000h5R-C5 for ietf-http-wg@listhub.w3.org; Wed, 11 Oct 2023 09:43:07 +0000
Received: from ded1.1wt.eu ([163.172.96.212] helo=1wt.eu) by mimas.w3.org with esmtp (Exim 4.94.2) (envelope-from <w@1wt.eu>) id 1qqVk8-0096c2-HI for ietf-http-wg@w3.org; Wed, 11 Oct 2023 09:43:07 +0000
Received: (from willy@localhost) by mail.home.local (8.17.1/8.17.1/Submit) id 39B9gsGQ024461; Wed, 11 Oct 2023 11:42:54 +0200
Date: Wed, 11 Oct 2023 11:42:54 +0200
From: Willy Tarreau <w@1wt.eu>
To: Mark Nottingham <mnot@mnot.net>
Cc: HTTP Working Group <ietf-http-wg@w3.org>
Message-ID: <ZSZuHu5iWdh5Rl3b@1wt.eu>
References: <997813D6-7A5B-49E2-A2C3-FCD1B2D5F5BC@mnot.net>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <997813D6-7A5B-49E2-A2C3-FCD1B2D5F5BC@mnot.net>
Received-SPF: pass client-ip=163.172.96.212; envelope-from=w@1wt.eu; helo=1wt.eu
X-W3C-Hub-Spam-Status: No, score=-7.9
X-W3C-Hub-Spam-Report: BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, W3C_AA=-1, W3C_IRA=-1, W3C_IRR=-3, W3C_WL=-1
X-W3C-Scan-Sig: mimas.w3.org 1qqVk8-0096c2-HI d9999ada91af81253280265e36f0f098
X-Original-To: ietf-http-wg@w3.org
Subject: Re: Prague side meeting: HTTP/2 concurrency and request cancellation (CVE-2023-44487)
Archived-At: <https://www.w3.org/mid/ZSZuHu5iWdh5Rl3b@1wt.eu>
Resent-From: ietf-http-wg@w3.org
X-Mailing-List: <ietf-http-wg@w3.org> archive/latest/51452
X-Loop: ietf-http-wg@w3.org
Resent-Sender: ietf-http-wg-request@w3.org
Precedence: list
List-Id: <ietf-http-wg.w3.org>
List-Help: <https://www.w3.org/email/>
List-Post: <mailto:ietf-http-wg@w3.org>
List-Unsubscribe: <mailto:ietf-http-wg-request@w3.org?subject=unsubscribe>
Hi Mark, On Wed, Oct 11, 2023 at 10:45:13AM +1100, Mark Nottingham wrote: > Martin has already drafted one proposal: > https://martinthomson.github.io/h2-stream-limits/draft-thomson-httpbis-h2-stream-limits.html I find that there are interesting points here. Yesterday my coworker Amaury who works on H3 explained to me how QUIC streams are flow- controlled and I found the principle much safer. I thought we could slightly emulate it by sending lots of SETTINGS frames and keeping track of which one advertised what so that we know what the client ACKs but that would be totally ugly and complicated. I do like Martin's idea above however. The only thing is that it will not protect servers against older clients, hence attackers would just act like an older client. And if for safety we decide to start lower with a small MAX_CONCURRENT_STREAMS then it would penalize modern clients during the first round trip. Or maybe we'd advertise both a low value for MAX_CONCURRENT_STREAMS for legacy clients immediately followed by a MAX_STREAMS frame advertising a larger one ? If so we still need to make sure that it will not cause massive RSTs from clients between the two :-/ Or maybe something like this could work: MAX_CONCURRENT_STREAMS = 100 MAX_STREAMS = 100 MAX_CONCURRENT_STREAMS = 10 Older clients would learn 100 then 10, possibly dropping excess streams, while new clients would learn MAX_STREAMS=100 and from that point ignore MAX_CONCURRENT_STREAMS=10. > Other discussions might touch on whether there are other measures (protocol > mechanisms or otherwise) that clients and servers can take, how concurrency > is exposed to calling code, and whether we can give better guidance about how > concurrency violations should be handled. A few of these were discussed already in the thread below opened by Cory 4 years ago, where it was discussed how to count streams vs limit, and where I even mentioned this exact method of attack consisting in sending HEADERS followed by RST_STREAM that would not change the total stream count from the protocol perspective: https://lists.w3.org/Archives/Public/ietf-http-wg/2019JanMar/0131.html We already faced that issue long ago when multiple haproxy instances were stacked on top of each other over H2 and too short timeouts on the front would cause long series of HEADERS+RST_STREAM on the back before the request had a chance to be processed due to the second layer being configured with a nice value making it slower than the first one. What we've been doing in haproxy against this is that instead of counting the streams at the protocol level, we count attached ones at the application layer: these are created at the same moment, but they're released once they're aware of the close. And we stop processing new streams once the configured limit is passed. This means that for a limit of 100 streams for example, if we receive 100 HEADERS and their 100 respective RST_STREAM, it will indeed create 100 streams that are immediately orphaned (and closed from an H2 perspective), but the 101th HEADERS frame will interrupt processing until some of these streams are effectively closed and freed (and not just at the protocol layer). And from what I've read below from Maxim Dounin, it seems like nginx applies a very similar strategy (they use x2 margin instead of +1 but the principle is the same, let streams finish first): https://mailman.nginx.org/pipermail/nginx-devel/2023-October/S36Q5HBXR7CAIMPLLPRSSSYR4PCMWILK.html As such, I suspect that these approaches might be much more common than what sensationalist mass media want us to believe and that the issue is more a matter of implementation choices (i.e. resource management) than of the protocol. We know that the protocol has some deficiencies that make naive implementations easily attackable (this one, setting stream windows of 1 byte during transfers, long series of 1-byte HEADERS+CONTINUATION, various forms of HOL blocking such as zero-windows, unlimited number of PUSH_PROMISE etc) but I think that once you care about your resource usage you have to make some reasonable compromises on all of these. With that said I'd love to plug that hole with an elegant mechanism involving just an optional new frame ;-) Cheers, Willy
- Prague side meeting: HTTP/2 concurrency and reque… Mark Nottingham
- Re: Prague side meeting: HTTP/2 concurrency and r… Willy Tarreau
- Re: Prague side meeting: HTTP/2 concurrency and r… Stefan Eissing
- Re: Prague side meeting: HTTP/2 concurrency and r… Willy Tarreau
- Re: Prague side meeting: HTTP/2 concurrency and r… Poul-Henning Kamp
- Re: Maxim Dounin
- Re: Willy Tarreau
- Re: Prague side meeting: HTTP/2 concurrency and r… Martin Thomson
- Re: Prague side meeting: HTTP/2 concurrency and r… Glenn Strauss
- Re: Prague side meeting: HTTP/2 concurrency and r… Martin Thomson
- Re: Prague side meeting: HTTP/2 concurrency and r… Kazuho Oku
- Re: Prague side meeting: HTTP/2 concurrency and r… Glenn Strauss
- Re: Prague side meeting: HTTP/2 concurrency and r… Martin Thomson
- Re: Prague side meeting: HTTP/2 concurrency and r… Willy Tarreau
- RE: Prague side meeting: HTTP/2 concurrency and r… Mike Bishop
- Re: Prague side meeting: HTTP/2 concurrency and r… Willy Tarreau
- Re: Prague side meeting: HTTP/2 concurrency and r… Stefan Eissing
- Re: Prague side meeting: HTTP/2 concurrency and r… Kazuho Oku
- Re: Prague side meeting: HTTP/2 concurrency and r… Poul-Henning Kamp
- Re: Prague side meeting: HTTP/2 concurrency and r… Stefan Eissing
- Re: Prague side meeting: HTTP/2 concurrency and r… Poul-Henning Kamp
- Re: Prague side meeting: HTTP/2 concurrency and r… Lucas Pardue
- Re: Prague side meeting: HTTP/2 concurrency and r… Kazuho Oku
- Re: Prague side meeting: HTTP/2 concurrency and r… Poul-Henning Kamp
- Re: Prague side meeting: HTTP/2 concurrency and r… Stefan Eissing
- Re: Prague side meeting: HTTP/2 concurrency and r… Watson Ladd
- Re: Prague side meeting: HTTP/2 concurrency and r… Lucas Pardue
- Re: Prague side meeting: HTTP/2 concurrency and r… Glenn Strauss
- Re: Prague side meeting: HTTP/2 concurrency and r… Mark Nottingham
- Re: Prague side meeting: HTTP/2 concurrency and r… Willy Tarreau
- Re: Prague side meeting: HTTP/2 concurrency and r… Roy T. Fielding
- Re: Prague side meeting: HTTP/2 concurrency and r… Lucas Pardue
- Re: Prague side meeting: HTTP/2 concurrency and r… Willy Tarreau
- Re: Prague side meeting: HTTP/2 concurrency and r… Mark Nottingham