cargo package report

Is praxis-proxy safe?

1 known vulnerability, worst severity HIGH.

// reach

0 direct dependencies

none carry a known advisory

    0 packages depend on it

    an advisory here reaches each of them

      Create a free accountfor every dependency path, dependent and what to upgrade
      // ai model usage

      Tracked for PyPI packages. HuggingFace models declare Python dependencies, so cargo packages are not covered.


      cvss
      0.0
      high

      severity band, no base score published

      epss
      not scored

      chance of exploitation in 30 days

      xyz score
      0.0
      low

      CyberXYZ composite out of 10

      fig. 01 — GHSA-cjcg-cxmh-9wcr, the advisory selected below

      // 1 advisories

      GHSA-cjcg-cxmh-9wcr

      HIGH
      // summary

      Multiple denial-of-service vulnerabilities have been discovered in HTTP/2 server implementations. All have been rated with a severity impact of Important. 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 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 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
      // cvss v3.1 vector

      CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

      Attack vector
      Network
      Attack complexity
      Low
      Privileges required
      None
      User interaction
      None
      Scope
      Unchanged
      Confidentiality
      None
      Integrity
      None
      Availability
      High

      Checked 2026-10-04 at 01:10 UTC. The most recent advisory here was published 2026-10-02. Updated continuously from NVD, GHSA, OSV and CNA feeds.

      Think a verdict here is wrong? Tell us — we respond within 2 business days.