{"answers":{"affected":"2 open source packages ship an affected version, including praxis-proxy.","exploited":"There is no known exploitation of GHSA-cjcg-cxmh-9wcr in the wild and no public exploit code.","fix":"Upgrade praxis-proxy to 0.5.2 or later.","what":"GHSA-cjcg-cxmh-9wcr is a denial of service vulnerability in praxis-proxy, published on 2 Oct 2026. An attacker can exploit it over the internet without logging in, with no action from the victim."},"fix_prompt":"Check this codebase for GHSA-cjcg-cxmh-9wcr and fix it if it is affected.\n\nWhat it is: GHSA-cjcg-cxmh-9wcr is a denial of service vulnerability in praxis-proxy, published on 2 Oct 2026. An attacker can exploit it over the internet without logging in, with no action from the victim.\nExploitation: There is no known exploitation of GHSA-cjcg-cxmh-9wcr in the wild and no public exploit code.\n\nAffected packages and fixed versions:\n- praxis-proxy (crates.io): affected all versions; fixed in 0.5.2\n- praxis-proxy (crates.io): affected all versions; fixed in 0.5.2\n\nTask:\n1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.\n2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.\n3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.\n4. Run the tests and summarise what changed and why.\n5. If nothing in the project is affected, say so and change nothing.\n\nReference: https://insights.sbomify.com/GHSA-cjcg-cxmh-9wcr/ (Markdown: https://insights.sbomify.com/GHSA-cjcg-cxmh-9wcr/index.md)","id":"GHSA-cjcg-cxmh-9wcr","markdown":"https://insights.sbomify.com/GHSA-cjcg-cxmh-9wcr/index.md","name":"GHSA-cjcg-cxmh-9wcr","record":{"aliases":[],"analysis":{"component_type":"server_software","fix_type":"upgrade","impacts":["denial_of_service"],"network_reachable":"yes","non_default_config":false,"product_category":"Praxis HTTP/2 proxy","requires_auth":"none","summary":"Remote attackers can cause denial of service in Praxis proxy by sending crafted HTTP/2 requests that trigger excessive memory allocation.","user_interaction":"not_required","vuln_class":"denial_of_service"},"analysis_generated_by":"qwen3.8-flash-next","assigner":null,"cpe":[],"cvss":{"score":null,"severity":null,"source":null,"vector":null,"version":null},"cwes":[],"description":"### Summary\n\nMultiple 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. \n\n### Details\n\nCredit to the original researcher, I'm mostly just run their tool against the code base.\n\n[Security Bulletins](https://access.redhat.com/security/vulnerabilities/RHSB-2026-007): https://access.redhat.com/security/vulnerabilities/RHSB-2026-007 \nExploit details: https://blog.calif.io/p/codex-discovered-a-hidden-http2-bomb\n\nThis 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)\n\n### PoC\n\n* Generate certificates\n```\nopenssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -keyout server.key -out server.crt -days 3650 -nodes -subj \"/CN=localhost\"\n```\n\n* Create praxis config as follow\n\n```\nlisteners:\n  - name: web\n    address: \"0.0.0.0:8443\"\n    tls:\n      certificates:\n        - cert_path: /etc/praxis/server.crt\n          key_path: /etc/praxis/server.key\n    filter_chains: [main]\n\nfilter_chains:\n  - name: main\n    filters:\n      - filter: router\n        routes:\n          - path_prefix: \"/\"\n            host: \"example.api.com\"\n            cluster: backend\n      - filter: load_balancer\n        clusters:\n          - name: backend\n            endpoints:\n              - \"httpbingo.org:443\"\n            tls:\n                verify: false\n```\n\n* Start the container\n\n```\ndocker 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\n```\n\n* Check container memory\n\n```\n$ docker stats\n\nCONTAINER ID   NAME            CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS\n362cfa472792   praxis          0.00%     6.473MiB / 62.49GiB   0.01%     7.57kB / 126B   0B / 0B          22\n```\n\n* In another terminal run the attack\n\n```\n./hpack_bomb.py --host 127.0.0.1 --port 8443 -n 10\n```\n\n* Observer the container memory\n\n```\n98b040c5e5ad   praxis          0.13%     687.1MiB / 62.49GiB   1.07%     41.6MB / 362kB   0B / 0B          23\n```\n\nMemory usage spiked to around 700MB, and even after the attack ended, the memory was not freed up.\n* Patch the code to set h2options\n\n```\ndiff --git a/protocol/src/http/pingora/handler/mod.rs b/protocol/src/http/pingora/handler/mod.rs\nindex dc684ad..fc59234 100644\n--- a/protocol/src/http/pingora/handler/mod.rs\n+++ b/protocol/src/http/pingora/handler/mod.rs\n@@ -18,6 +18,7 @@ use std::{collections::HashMap, sync::Arc, time::Duration};\n\n use arc_swap::ArcSwap;\n use bytes::Bytes;\n+use pingora_core::protocols::http::v2::server::H2Options;\n use pingora_core::{Result, apps::HttpServerOptions, server::Server, services::listening::Service};\n use pingora_proxy::{Session, http_proxy};\n use praxis_core::{config::ABSOLUTE_MAX_BODY_BYTES, connectivity::Upstream};\n@@ -151,6 +152,11 @@ where\n     let service_name = format!(\"http-proxy:{name}\", name = listener.name);\n     let mut proxy = http_proxy(\u0026server.configuration, handler);\n     proxy.server_options = Some(h2c_server_options());\n+    let mut h2_options = H2Options::new();\n+    h2_options.max_header_list_size(65536);\n+    h2_options.max_concurrent_streams(32);\n+    proxy.h2_options = Some(h2_options);\n+\n     let mut service = Service::new(service_name, proxy);\n     if let Some(tx) = super::listener::add_listener(\u0026mut service, listener)? {\n         cert_watcher_shutdowns.push(tx);\n```\n\n* Rerun the attack, the memory usage looks a lot better now\n\n```\nCONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O    PIDS\nb1c82abca409   praxis    0.04%     10.09MiB / 62.49GiB   0.02%     1.16MB / 23.4kB   950kB / 0B   23\n```","ecosystems":["crates.io"],"exploits":{"exploitdb":null,"first_seen":null,"github_poc":null,"max_poc_stars":null,"metasploit":null,"nuclei":null,"refs":[],"tier":null},"has_fix":true,"headline":"Praxis affected by HTTP/2 Bomb","id":"GHSA-cjcg-cxmh-9wcr","indexable":true,"kev":null,"kind":"advisory","links":{"ecosystem":"crates.io","product":null,"products":[],"type":"denial_of_service","year":"2026"},"n_packages":2,"n_references":null,"packages":[{"ecosystem":"crates.io","fixed":["0.5.2"],"introduced":["0"],"last_affected":[],"package":"praxis-proxy","purl":null,"source":"GHSA-cjcg-cxmh-9wcr"},{"ecosystem":"crates.io","fixed":["0.5.2"],"introduced":["0"],"last_affected":[],"package":"praxis-proxy","purl":"pkg:cargo/praxis-proxy","source":"GHSA-cjcg-cxmh-9wcr"}],"products":null,"published":"2026-10-02","related":[],"sources":[{"class":"attribution","licence":"CC BY 4.0","name":"GitHub Advisory Database","prefix":"GHSA"}],"ssvc":{"automatable":null,"exploitation":null,"technical_impact":null},"state":null,"updated":null,"vendors":null},"summary":"Remote attackers can cause denial of service in Praxis proxy by sending crafted HTTP/2 requests that trigger excessive memory allocation.","url":"https://insights.sbomify.com/GHSA-cjcg-cxmh-9wcr/"}