cloudflare/pingora
Security
Pingora's "reasons to use" list opens with security: a memory-safe alternative to C/C++ proxies. This page covers what that means in practice, plus the trust boundaries and security hygiene the codebase enforces.
Memory safety
Pingora is 100% safe Rust except for narrow unsafe blocks in:
- TLS backend FFI (
pingora-openssl,pingora-boringssl,pingora-s2n) — calls into C TLS libraries - Low-level POSIX syscalls (
pingora-core/src/server/transfer_fd/) —SCM_RIGHTSFD passing
The unsafe surface is small enough to audit in an afternoon. The TLS library choice is the largest unmanaged-memory dependency.
Trust boundaries
graph LR
Untrusted["Untrusted: client TCP/TLS"]
Listener["Listener<br/>(pingora-core/src/listeners)"]
Filter["ConnectionFilter<br/>(optional)"]
TLS["TLS handshake"]
Session["HTTP session<br/>(pingora-core)"]
Proxy["ProxyHttp impl<br/>(user code)"]
Connector["Upstream connector<br/>(pingora-core)"]
Upstream["Upstream<br/>(semi-trusted)"]
Untrusted --> Listener --> Filter --> TLS --> Session --> Proxy --> Connector --> UpstreamThe clear trust boundary is between the L4 listener and the application code. Everything below Filter is treated as adversarial; everything above is application logic.
Connection filtering
The connection_filter cargo feature lets a ConnectionFilter reject connections before TLS handshake based on remote IP, peer address, or any other L4-visible attribute. Useful for IP blocklists, geo-rejection, or rate limiting at the edge of the trust boundary. See TLS options.
Input validation
The HTTP/1 parser (pingora-core/src/protocols/http/v1/server.rs) uses httparse (workspace dependency, version 1). The 0.8.0 release added stricter validation:
- Reject invalid Content-Length on HTTP/1 requests to eliminate ambiguous request framing.
- Validate Content-Length on HTTP/1 responses by default; remove
Content-LengthwhenTransfer-Encodingis also present (RFC compliance).
The HTTP/2 implementation uses the h2 crate (workspace dependency, >=0.4.11). The version pin floor exists because h2 versions before 0.4.11 had RST_STREAM handling bugs.
CONNECT method
In 0.8.0, CONNECT proxying is disabled by default. Servers had been seeing it used as an attack vector (HTTP smuggling). Enable it explicitly via server options if your service intentionally supports CONNECT.
Timeouts
Untrusted-input handling needs timeouts. Pingora applies them at:
- TCP accept (configurable via listeners)
- TLS handshake (
tls_handshake_timeoutper peer) - HTTP/1 read (
read_timeoutper session) - HTTP/1 write (
write_timeoutper session) — used consistently on H2 body writes as of 0.7.0 - H2 application read (sends RST_STREAM CANCEL on application read timeouts as of 0.7.0)
If you don't set timeouts, defaults apply. They are not "infinite."
TLS
- Pre-set cipher lists.
TlsSettings::intermediateandTlsSettings::modernuse the Mozilla-recommended cipher lists. - Cert verification on by default for upstreams. Set
verify_cert: falseonHttpPeer.optionsonly if you mean it. - Hostname verification is separate from cert verification. Both are recommended.
- mTLS support is built in (0.7.0). See TLS options.
- Client cert verification for mTLS configuration was added in 0.8.0.
Secret handling
Pingora doesn't manage secrets itself. The Sentry integration is configured via the YAML config; if your DSN contains a secret, your config file is sensitive. The TLS keys are loaded from disk paths you supply.
The codebase carefully avoids logging request headers wholesale. Custom proxy code that logs headers should redact Authorization, Cookie, and similar.
Dependency security
.github/workflows/audit.ymlrunscargo auditon every push..github/workflows/semgrep.yml(added Apr 2026) runs Semgrep OSS rules.- The 0.7.0 release upgraded
lruto>=0.16.3because of RUSTSEC-2026-0002. - The 0.7.0 release also removed
atty(RUSTSEC). - Workspace deps pin
h2 = ">=0.4.11"to dodge known HTTP/2 vulns.
Sandboxing and process privilege
The YAML config supports user: and group: to drop privileges after binding listening ports. Useful when you need to bind low ports but don't want to run as root.
Reporting vulnerabilities
The README and CONTRIBUTING file point at opensource@cloudflare.com for general questions. Cloudflare runs a HackerOne program for vulnerability reports — the README doesn't link directly but the parent cloudflare/.github org repository has the canonical security policy.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.