GHSA-cjcg-cxmh-9wcr
Praxis affected by HTTP/2 Bomb
Details
### Summary
Multiple denial-of-service vulnerabilities have been discovered in HTTP/2 server implementations. All have been rated with a severity impact of [Important](https://access.redhat.com/security/updates/classification). The vulnerabilities target HPACK, the header compression scheme in HTTP/2, where a small request can trigger large memory allocations on the server.
### Details
Credit to the original researcher, I'm mostly just run their tool against the code base.
[Security Bulletins](https://access.redhat.com/security/vulnerabilities/RHSB-2026-007): https://access.redhat.com/security/vulnerabilities/RHSB-2026-007 Exploit details: https://blog.calif.io/p/codex-discovered-a-hidden-http2-bomb
This bug was fixed in upstream pingora v0.8.1, but our fork (v0.8.2) is missing this important [PR](https://github.com/praxis-proxy/pingora/commit/d193c8d49b8b7c1c1ede93183759caa4f6906bbd) to set the default h2 options. (edited)
### PoC
* Generate certificates ``` openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -keyout server.key -out server.crt -days 3650 -nodes -subj "/CN=localhost" ```
* Create praxis config as follow
``` listeners: - name: web address: "0.0.0.0:8443" tls: certificates: - cert_path: /etc/praxis/server.crt key_path: /etc/praxis/server.key filter_chains: [main]
filter_chains: - name: main filters: - filter: router routes: - path_prefix: "/" host: "example.api.com" cluster: backend - filter: load_balancer clusters: - name: backend endpoints: - "httpbingo.org:443" tls: verify: false ```
* Start the container
``` docker run --name praxis --user $(id -u):$(id -g) -it --rm -p 8443:8443 -v ./config.yaml:/etc/praxis/config.yaml -v ./server.crt:/etc/praxis/server.crt -v ./server.key:/etc/praxis/server.key ghcr.io/praxis-proxy/praxis:0.5.1 ```
* Check container memory
``` $ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 362cfa472792 praxis 0.00% 6.473MiB / 62.49GiB 0.01% 7.57kB / 126B 0B / 0B 22 ```
* In another terminal run the attack
``` ./hpack_bomb.py --host 127.0.0.1 --port 8443 -n 10 ```
* Observer the container memory
``` 98b040c5e5ad praxis 0.13% 687.1MiB / 62.49GiB 1.07% 41.6MB / 362kB 0B / 0B 23 ```
Memory usage spiked to around 700MB, and even after the attack ended, the memory was not freed up. * Patch the code to set h2options
``` diff --git a/protocol/src/http/pingora/handler/mod.rs b/protocol/src/http/pingora/handler/mod.rs index dc684ad..fc59234 100644 --- a/protocol/src/http/pingora/handler/mod.rs +++ b/protocol/src/http/pingora/handler/mod.rs @@ -18,6 +18,7 @@ use std::{collections::HashMap, sync::Arc, time::Duration};
use arc_swap::ArcSwap; use bytes::Bytes; +use pingora_core::protocols::http::v2::server::H2Options; use pingora_core::{Result, apps::HttpServerOptions, server::Server, services::listening::Service}; use pingora_proxy::{Session, http_proxy}; use praxis_core::{config::ABSOLUTE_MAX_BODY_BYTES, connectivity::Upstream}; @@ -151,6 +152,11 @@ where let service_name = format!("http-proxy:{name}", name = listener.name); let mut proxy = http_proxy(&server.configuration, handler); proxy.server_options = Some(h2c_server_options()); + let mut h2_options = H2Options::new(); + h2_options.max_header_list_size(65536); + h2_options.max_concurrent_streams(32); + proxy.h2_options = Some(h2_options); + let mut service = Service::new(service_name, proxy); if let Some(tx) = super::listener::add_listener(&mut service, listener)? { cert_watcher_shutdowns.push(tx); ```
* Rerun the attack, the memory usage looks a lot better now
``` CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b1c82abca409 praxis 0.04% 10.09MiB / 62.49GiB 0.02% 1.16MB / 23.4kB 950kB / 0B 23 ```
Are you affected?
Enter the version of the package you're using.
Affected packages
0Fixed in: 0.5.2Upgrade praxis-proxy to 0.5.2 or newer (ecosystem crates.io).
References
- https://github.com/praxis-proxy/praxis/security/advisories/GHSA-cjcg-cxmh-9wcr[WEB]
- https://github.com/praxis-proxy/praxis/commit/2bb7b29d6992fc2d8045628475912d734e6bee97[WEB]
- https://access.redhat.com/security/vulnerabilities/RHSB-2026-007[WEB]
- https://blog.calif.io/p/codex-discovered-a-hidden-http2-bomb[WEB]
- https://github.com/praxis-proxy/praxis[PACKAGE]
- https://github.com/praxis-proxy/praxis/releases/tag/v0.5.2[WEB]