
Repository with controlled validation scripts for behaviors associated with CVEs CVE-2019-9511 and CVE-2019-9513, both related to denial of service vectors in HTTP/2 implementations.
The scripts were created to support technical validations in authorized environments, allowing observation of whether the server negotiates HTTP/2 and responds to specific patterns related to Data Dribble and Priority Churn, without executing a denial of service attack.
The proposal is to demonstrate the vector in a light and safe manner, with low request volume and without the intention of making the environment unavailable.
| CVE | Name | Script | Description |
|---|---|---|---|
CVE-2019-9511 | HTTP/2 Data Dribble | data_dribble_probe.py | Validates HTTP/2 flow control behavior by releasing small volumes of data in a controlled manner. |
CVE-2019-9513 | HTTP/2 Priority Churn / Resource Loop | priority_churn_probe.py | Validates processing behavior of PRIORITY frames at low intensity. |
CVE-2019-9511, known as HTTP/2 Data Dribble, affects some HTTP/2 implementations that do not efficiently handle flow window manipulation and gradual data delivery.
In this scenario, an attacker can request data from the server and manipulate flow control to keep the response open and deliver it in small blocks, such as 1-byte packets. Depending on the implementation, this behavior can cause excessive CPU, memory, or connection resource consumption, resulting in a denial of service risk.
In this repository, the related script is:
data_dribble_probe.py
The script's objective is to validate the behavior lightly, without generating aggressive load and without attempting to cause unavailability.
References:
CVE-2019-9513, known as HTTP/2 Priority Churn or Resource Loop, affects some HTTP/2 implementations that process continuous changes to the stream priority tree in a costly manner.
In this scenario, an attacker can create multiple streams and repeatedly change the priority between them, causing churn in the priority tree. Depending on the implementation, this behavior can cause excessive CPU consumption and lead to denial of service.
In this repository, the related script is:
priority_churn_probe.py
The script's objective is to validate whether the server accepts and processes PRIORITY frames, using low intensity and without executing a DoS attack.
References:
The CVEs CVE-2019-9511 and CVE-2019-9513 are not associated with a single specific version of a web server, such as only nginx, Apache, or Tomcat.
They affect certain HTTP/2 implementations in different products, libraries, proxies, load balancers, and servers. Therefore, validation should consider which component is negotiating and processing HTTP/2 in the analyzed environment.
Examples of components that may be involved:
nginx
Apache HTTP Server
Envoy
HAProxy
Tomcat
Jetty
Node.js
Go net/http2
nghttp2
CDN
WAF
Load Balancer
Ingress Controller Kubernetes
The first technical criterion is to confirm whether the service negotiates HTTP/2 via ALPN. If the service does not negotiate h2, these scripts are not applicable.
Confirmation of vulnerability by version should be based on the manufacturer's official advisory for the identified component.
Before running the scripts, validate whether the target negotiates HTTP/2 via ALPN.
Use only the domain in the command, without https://.
openssl s_client -alpn h2 -connect exemplo.com.br:443 </dev/null 2>/dev/null | grep -i "ALPN"
You can also use a placeholder:
openssl s_client -alpn h2 -connect <HOST>:443 </dev/null 2>/dev/null | grep -i "ALPN"
Expected output:
ALPN protocol: h2
If the output indicates h2, the service negotiates HTTP/2 and the scripts may be applicable.
If there is no return or the negotiated protocol is another, such as http/1.1, the scripts are not applicable for that endpoint.
The most logical order for using the scripts is:
1. HTTP/2 pre-validation with openssl
↓
2. priority_churn_probe.py
↓
3. data_dribble_probe.py
First, use the command with openssl to confirm whether the target negotiates HTTP/2. Then use priority_churn_probe.py to validate whether the server accepts and processes priority frames. Next, use data_dribble_probe.py to observe the server's behavior when faced with a reduced flow window, releasing small volumes of data in a controlled manner.
Both scripts are lightweight probes. They are not intended to cause unavailability, but rather to generate technical evidence of the observed behavior.
priority_churn_probe.py is a lightweight PoC for behavioral validation related to CVE-2019-9513, known as HTTP/2 Priority Churn.
The script establishes an HTTP/2 connection via TLS, opens small HTTP streams, and sends priority changes via PRIORITY frames. Then it measures latency before and after sending these frames to observe any variation in processing.
PING;PRIORITY frames at low intensity;Use this script when it is necessary to validate whether an HTTP/2 server accepts and processes priority frames related to the Priority Churn vector, without performing an aggressive DoS test.
It is appropriate for controlled validation in pentests, HTTP/2 exposure analysis, and technical proof of vulnerable or potentially sensitive behavior.
The script receives values via command line arguments:
--host
--port
--paths
--shuffles
Use light, public, low-impact paths, such as:
/
/robots.txt
/favicon.ico
/health
/login
Avoid paths that execute heavy operations, complex queries, report generation, upload, advanced search, or any functionality that generates load on the backend.
python3 priority_churn_probe.py --host exemplo.com.br --port 443 --paths / /robots.txt /favicon.ico --shuffles 10
Example output:
[OK] PING before: 45.20 ms; after churn: 52.80 ms; shuffles=10
Signal 9513: PRIORITY frames accepted and processed; subtle increase post-churn evidences the vector (without DoS).
If the script successfully negotiates HTTP/2, opens streams, and sends PRIORITY frames, this indicates that the server processes this type of behavior.
A subtle increase in latency after the churn can be used as technical evidence that the vector exists, but it should not be interpreted alone as proof of severe impact. Final classification depends on context, server version, architecture, mitigators, WAF/CDN, and HTTP/2 configuration.
data_dribble_probe.py is a lightweight PoC for behavioral validation related to CVE-2019-9511, known as HTTP/2 Data Dribble.
The script establishes an HTTP/2 connection via TLS, opens a single stream, and manipulates the flow control window to release small volumes of data, simulating the gradual delivery behavior of DATA frames.
Use this script when it is necessary to validate whether the HTTP/2 server responds to a reduced flow control pattern, associated with the Data Dribble vector, without executing aggressive load.
It is appropriate for controlled technical proof, especially when automated tools point to possible exposure and manual validation with lower operational risk is needed.
The script receives values via command line arguments:
--host
--path
--port
--bytes
Use a simple, static, or low-cost path for the server, such as:
/
/robots.txt
/favicon.ico
/health
/login
Avoid endpoints that perform database queries, heavy authentication, asynchronous processing, document generation, or calls to internal systems.
python3 data_dribble_probe.py --host exemplo.com.br --path / --port 443 --bytes 12
Example output:
[OK] HTTP/2 negotiated; DATA frames received: 12; bytes released: 12; time(ms): 1450
Signal 9511: multiple tiny DATA frames delivered under window=1 (proof of 'dribble' path without stress).
If the script negotiates HTTP/2 and receives small DATA frames as the flow window is released, this indicates that the server processes this flow control pattern.
This behavior can be used as technical evidence of the vector, but criticality should consider the actual environment context, such as server used, version, connection limits, load balancer, CDN, WAF, timeout, and abuse protections.
The scripts require Python 3 and the h2 library.
python3
pip
h2
ssl
socket
argparse
The libraries ssl, socket, time, argparse, and select are part of the Python standard library.
The main external dependency is:
h2
Direct installation:
python3 -m pip install h2
Installation using a virtual environment:
python3 -m venv venv
source venv/bin/activate
pip install h2
Verify the installation:
python3 -c "import h2; print('h2 installed successfully')"
The scripts depend on HTTP/2 negotiation via ALPN.
Before running, confirm whether the server supports HTTP/2:
openssl s_client -alpn h2 -connect exemplo.com.br:443 </dev/null 2>/dev/null | grep -i "ALPN"
Expected output:
ALPN protocol: h2
If the server does not negotiate h2, the scripts will not be applicable.
--host parameterDo not include https:// in the --host parameter.
Correct:
--host exemplo.com.br
Incorrect:
--host https://exemplo.com.br
Prefer simple paths:
/
/robots.txt
/favicon.ico
/health
Avoid sensitive or heavy endpoints:
/relatorios
/export
/search
/upload
/api/processamento
The idea is to validate HTTP/2 behavior, not to stress the backend.
Use conservative values:
For priority_churn_probe.py:
--shuffles 10
For data_dribble_probe.py:
--bytes 12
Do not increase these values in production without explicit authorization.
openssl s_client -alpn h2 -connect exemplo.com.br:443 </dev/null 2>/dev/null | grep -i "ALPN"
python3 priority_churn_probe.py --host exemplo.com.br --port 443 --paths / /robots.txt /favicon.ico --shuffles 10
python3 data_dribble_probe.py --host exemplo.com.br --path / --port 443 --bytes 12
To reduce risks associated with HTTP/2 DoS attacks, it is recommended to keep web servers, proxies, load balancers, and HTTP/2 libraries up to date, apply connection limits, configure appropriate timeouts, limit the number of simultaneous streams, restrict abuse of HTTP/2 frames, monitor latency anomalies, and evaluate disabling HTTP/2 on services that do not need this protocol.
It is also recommended to validate protection in layers such as CDN, WAF, reverse proxy, ingress controller, and load balancer, as often the real exposure depends more on the edge than on the final application.
Confirmation of remediation should be based on the component that actually terminates and processes HTTP/2 in the environment, such as web server, proxy, load balancer, CDN, or ingress controller.
These scripts should only be used in authorized environments.
Although they are written for lightweight execution, they directly interact with HTTP/2 mechanisms related to DoS vectors. Therefore, usage must be aligned with the formal test scope, engagement rules, and operational limits defined with the environment owner.
Before running in production, confirm:
Use of these scripts against systems without authorization is prohibited.
The purpose of this repository is exclusively to support legitimate security activities, such as authorized pentesting, controlled vulnerability validation, laboratories, technical study, and safe risk demonstration.
| Script | Related CVE | Objective | When to use |
|---|
data_dribble_probe.py | CVE-2019-9511 | Validate behavior associated with Data Dribble using window control to release small data blocks | Use when the server supports HTTP/2 and there is a need to verify DATA frame delivery behavior with a reduced window. |
priority_churn_probe.py | CVE-2019-9513 | Validate behavior associated with Priority Churn using PRIORITY frames at low intensity | Use when the server supports HTTP/2 and there is a need to verify if it processes stream priority changes. |
| Parameter | Description |
|---|
--host | FQDN of the authorized target. Do not include https://. |
--port | TLS port where the HTTP/2 service is available. Default: 443. |
--paths | List of simple paths to open HTTP/2 streams. |
--shuffles | Number of priority change cycles. Keep low for safe testing. |
| Parameter | Description |
|---|
--host | FQDN of the authorized target. Do not include https://. |
--path | Path to be requested in the test. |
--port | TLS port where the HTTP/2 service is available. Default: 443. |
--bytes | Total bytes released during the test. Keep low for safe validation. |