Every CVESearch/Get API key

GHSA-vpp8-g58w-m8mp

Twisted: Unauthenticated Remote Denial of Service in the Twisted HTTP/2 Server via Rapid Stream Reset

7.5 HighFix available

Summary

An uncontrolled-resource-consumption vulnerability (CWE-400) in the Twisted HTTP/2 server lets any unauthenticated remote client exhaust server CPU over a single connection. A client that sends a request header block with END_STREAM and then immediately resets the stream makes the server route and render the request before it processes the reset. Reset streams are freed and never count against the concurrent-stream limit, and no reset-rate limiter exists, so the pattern can be repeated at line rate on one connection. This is the HTTP/2 Rapid Reset class, CVE-2023-44487.

Details

For one received segment the h2 events are processed in order in H2Connection.dataReceived. A HEADERS(END_STREAM) followed by RST_STREAM yields RequestReceived, StreamEnded, then StreamReset, so the request is dispatched and rendered on stream end before the reset is handled:

# src/twisted/web/_http2.py  (H2Connection.dataReceived)
for event in events:
    if isinstance(event, h2.events.RequestReceived):
        self._requestReceived(event)     # allocate the request
    elif isinstance(event, h2.events.StreamEnded):
        self._requestEnded(event)        # -> requestComplete -> render() synchronously
    elif isinstance(event, h2.events.StreamReset):
        self._requestAborted(event)      # processed last, frees the stream

_requestAborted frees the reset stream, so it never occupies the 100-stream concurrency budget, and nothing in _http2.py counts or throttles opened-and-reset streams. The 2019 flood fix (GHSA-32gv) bounds outbound control-frame buffering only and does not apply to this path.

Affected product: Twisted, twisted.web HTTP/2 server Affected versions: confirmed against 26.4.0

PoC

On any Twisted HTTP/2 endpoint, open one connection and, in a tight loop, send a HEADERS frame with END_STREAM on a fresh stream identifier immediately followed by a RST_STREAM for that stream, at line rate. No credentials are required. The server renders each request on stream end before the reset frees the stream, and a freed stream never counts toward the concurrent-stream limit, so the loop is never throttled.

Because every cancelled stream is still dispatched in full and reset streams do not accumulate, the connection is never throttled or closed, so the forced work grows with the number of pairs sent. Sustained on one connection this saturates a CPU core under only a trickle of traffic, whereas a client that instead leaves its streams open is closed once it reaches the concurrent-stream limit.

Impact

This is an unauthenticated remote denial of service (CWE-400, CWE-770) by CPU exhaustion. One connection forces unbounded request rendering at a few frames per cancelled request, bypassing the concurrent-stream limit. It is the HTTP/2 Rapid Reset class (CVE-2023-44487), not covered by the earlier Twisted flood fix, with no confidentiality or integrity impact and no code execution.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

What each source reports

GitHub Advisories Score used7.5

Twisted: Unauthenticated Remote Denial of Service in the Twisted HTTP/2 Server via Rapid Stream Reset

Summary

An uncontrolled-resource-consumption vulnerability (CWE-400) in the Twisted HTTP/2 server lets any unauthenticated remote client exhaust server CPU over a single connection. A client that sends a request header block with END_STREAM and then immediately resets the stream makes the server route and render the request before it processes the reset. Reset streams are freed and never count against the concurrent-stream limit, and no reset-rate limiter exists, so the pattern can be repeated at line rate on one connection. This is the HTTP/2 Rapid Reset class, CVE-2023-44487.

Details

For one received segment the h2 events are processed in order in H2Connection.dataReceived. A HEADERS(END_STREAM) followed by RST_STREAM yields RequestReceived, StreamEnded, then StreamReset, so the request is dispatched and rendered on stream end before the reset is handled:

# src/twisted/web/_http2.py  (H2Connection.dataReceived)
for event in events:
    if isinstance(event, h2.events.RequestReceived):
        self._requestReceived(event)     # allocate the request
    elif isinstance(event, h2.events.StreamEnded):
        self._requestEnded(event)        # -> requestComplete -> render() synchronously
    elif isinstance(event, h2.events.StreamReset):
        self._requestAborted(event)      # processed last, frees the stream

_requestAborted frees the reset stream, so it never occupies the 100-stream concurrency budget, and nothing in _http2.py counts or throttles opened-and-reset streams. The 2019 flood fix (GHSA-32gv) bounds outbound control-frame buffering only and does not apply to this path.

Affected product: Twisted, twisted.web HTTP/2 server Affected versions: confirmed against 26.4.0

PoC

On any Twisted HTTP/2 endpoint, open one connection and, in a tight loop, send a HEADERS frame with END_STREAM on a fresh stream identifier immediately followed by a RST_STREAM for that stream, at line rate. No credentials are required. The server renders each request on stream end before the reset frees the stream, and a freed stream never counts toward the concurrent-stream limit, so the loop is never throttled.

Because every cancelled stream is still dispatched in full and reset streams do not accumulate, the connection is never throttled or closed, so the forced work grows with the number of pairs sent. Sustained on one connection this saturates a CPU core under only a trickle of traffic, whereas a client that instead leaves its streams open is closed once it reaches the concurrent-stream limit.

Impact

This is an unauthenticated remote denial of service (CWE-400, CWE-770) by CPU exhaustion. One connection forces unbounded request rendering at a few frames per cancelled request, bypassing the concurrent-stream limit. It is the HTTP/2 Rapid Reset class (CVE-2023-44487), not covered by the earlier Twisted flood fix, with no confidentiality or integrity impact and no code execution.

Record
GHSA-vpp8-g58w-m8mp
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-770
Updated
2026-11-02
OSV7.5

Twisted: Unauthenticated Remote Denial of Service in the Twisted HTTP/2 Server via Rapid Stream Reset

Summary

An uncontrolled-resource-consumption vulnerability (CWE-400) in the Twisted HTTP/2 server lets any unauthenticated remote client exhaust server CPU over a single connection. A client that sends a request header block with END_STREAM and then immediately resets the stream makes the server route and render the request before it processes the reset. Reset streams are freed and never count against the concurrent-stream limit, and no reset-rate limiter exists, so the pattern can be repeated at line rate on one connection. This is the HTTP/2 Rapid Reset class, CVE-2023-44487.

Details

For one received segment the h2 events are processed in order in H2Connection.dataReceived. A HEADERS(END_STREAM) followed by RST_STREAM yields RequestReceived, StreamEnded, then StreamReset, so the request is dispatched and rendered on stream end before the reset is handled:

# src/twisted/web/_http2.py  (H2Connection.dataReceived)
for event in events:
    if isinstance(event, h2.events.RequestReceived):
        self._requestReceived(event)     # allocate the request
    elif isinstance(event, h2.events.StreamEnded):
        self._requestEnded(event)        # -> requestComplete -> render() synchronously
    elif isinstance(event, h2.events.StreamReset):
        self._requestAborted(event)      # processed last, frees the stream

_requestAborted frees the reset stream, so it never occupies the 100-stream concurrency budget, and nothing in _http2.py counts or throttles opened-and-reset streams. The 2019 flood fix (GHSA-32gv) bounds outbound control-frame buffering only and does not apply to this path.

Affected product: Twisted, twisted.web HTTP/2 server Affected versions: confirmed against 26.4.0

PoC

On any Twisted HTTP/2 endpoint, open one connection and, in a tight loop, send a HEADERS frame with END_STREAM on a fresh stream identifier immediately followed by a RST_STREAM for that stream, at line rate. No credentials are required. The server renders each request on stream end before the reset frees the stream, and a freed stream never counts toward the concurrent-stream limit, so the loop is never throttled.

Because every cancelled stream is still dispatched in full and reset streams do not accumulate, the connection is never throttled or closed, so the forced work grows with the number of pairs sent. Sustained on one connection this saturates a CPU core under only a trickle of traffic, whereas a client that instead leaves its streams open is closed once it reaches the concurrent-stream limit.

Impact

This is an unauthenticated remote denial of service (CWE-400, CWE-770) by CPU exhaustion. One connection forces unbounded request rendering at a few frames per cancelled request, bypassing the concurrent-stream limit. It is the HTTP/2 Rapid Reset class (CVE-2023-44487), not covered by the earlier Twisted flood fix, with no confidentiality or integrity impact and no code execution.

Record
GHSA-vpp8-g58w-m8mp
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-770
Updated
2026-11-02
OSVCLSA-2026-1793871747No score

TuxCare security update for twisted (1 CVE)

TuxCare rebuilt twisted to address 1 CVE. Fixed in 20.3.0.post9+tuxcare.

Record
CLSA-2026-1793871747
Updated
2026-11-05

Affected packages

Affected packages
PackageAffectedFixed
twisted
PyPI
through 26.4.0
26.10.0rc1
twisted
TuxCare:PyPI
20.3.0 up to 20.3.0.post9+tuxcare, plus listed versions
20.3.0.post4+tuxcare20.3.0.post5+tuxcare20.3.0.post6+tuxcare20.3.0.post7+tuxcare20.3.0.post8+tuxcare
20.3.0.post9+tuxcare
twisted
PyPI
before 26.10.0rc1, plus listed versions
1.0.11.0.31.0.41.0.51.0.6
Show 45 moreShow less
1.0.71.1.01.1.11.2.010.0.010.1.010.2.011.0.011.1.012.0.012.1.012.2.012.3.013.0.013.1.013.2.014.0.014.0.114.0.215.0.015.1.015.2.015.2.115.3.015.4.015.5.016.0.016.1.016.1.116.2.016.3.016.3.116.3.216.4.016.4.116.5.016.5.0rc116.5.0rc216.6.016.6.0rc116.7.0rc116.7.0rc217.1.017.1.0rc117.5.0
26.10.0rc1

History

History
RecordedChangedSources
affected, aliases, factsOSV
first indexedGitHub Advisories, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

GHSA-vpp8-g58w-m8mp is a high vulnerability (CVSS 7.5) in twisted, published October 29, 2026. No source lists public exploit code. Fixed in twisted 26.10.0rc1.

References

This page doesn't list everything

Left out here: 61 versions. The JSON record has them.

MoveEnter Open