Subject
h2 0.4.14 is an asynchronous HTTP/2 client and server library for Rust, implementing RFC 9113 (formerly RFC 7540). It is the HTTP/2 transport used by hyper and therefore a foundational dependency across much of the Rust web ecosystem. The crate handles frame parsing, HPACK header compression/decompression, flow-control accounting, stream multiplexing, and connection lifecycle management. It does not handle TLS or TCP; callers supply a pre-established AsyncRead + AsyncWrite transport.
Methodology
The published crate contents were compared against the upstream Git repository at the commit recorded in .cargo_vcs_info.json using diff -rq. The differences were limited to cargo normalization in Cargo.toml and directories excluded from publication (tests/, fuzz/, fixtures/, ci/, util/), which are all present in the VCS checkout. No source-file differences were found.
All 53 Rust source files (~26k LOC) were read. Files read in full include the entire src/hpack/ subtree (decoder, encoder, header, Huffman table+codec, table), src/frame/headers.rs, src/codec/framed_read.rs, src/proto/streams/flow_control.rs, src/proto/streams/recv.rs, src/proto/streams/counts.rs, src/proto/streams/streams.rs (first 200 lines; architecture confirmed), src/proto/connection.rs, and src/lib.rs. The remaining modules (server.rs, client.rs, share.rs, proto/settings.rs, proto/ping_pong.rs, etc.) were read in full for DoS-related logic and grep-surveyed for unsafe and I/O.
Tools: grep (macOS 14.x), diff, find, wc.
Unsafe-code survey: grep -rEn 'unsafe\s*(\{|fn|impl|trait)' found exactly one unsafe block in the entire crate (src/hpack/header.rs:283). FFI survey: no extern "C" declarations found. Network/filesystem survey: no direct socket or file I/O; the crate operates on caller-supplied I/O objects.
The VCS repository's tests/ and fuzz/ directories were examined to characterize the test suite.
The CHANGELOG was read for security-relevant entries. RUSTSEC was not queried directly; known advisories are addressed in the changelog (CVE-2023-26964, addressed in 0.3.17; Rapid Reset addressed in 0.3.17/0.4.2).
Results
The published crate matches VCS byte-for-byte on all source files. No binary artifacts are present, justifying has-binaries. There is no build.rs and no proc-macro, justifying has-build-exec and has-install-exec.
The single unsafe block is in BytesStr::as_str (src/hpack/header.rs:283), which calls from_utf8_unchecked. The invariant is established by BytesStr::try_from, which checks UTF-8 validity before constructing the type. The block carries a // Safety: comment. This justifies uses-unsafe, unsafe-safe, unsafe-documented, and unsafe-minimal.
The codebase contains no cryptographic operations (uses-crypto, impl-crypto are false), no filesystem or network I/O beyond the caller-supplied I/O handle (uses-filesystem, uses-network, uses-exec are false), and no environment variable access (uses-environment false). No JIT (uses-jit, impl-jit false), interpreter (uses-interpreter, impl-interpreter false), data structure (impl-datastructure false), or standalone algorithm (impl-algorithm false) implementations are present. No obfuscated code, base64 payloads, or suspicious network endpoints were found, justifying is-benign. impl-concurrency is false: the crate uses tokio and std mutexes but implements no concurrency primitives.
Shared stream state is protected by Arc<Mutex<Inner>> in src/proto/streams/streams.rs. Every public method acquires this lock before touching stream state. MAX_CONCURRENT_STREAMS is enforced on both send and receive sides via Counts. This justifies uses-concurrency, concurrency-safe, and concurrency-documented.
DoS mitigations present in this version:
HPACK bomb / decompression amplification: src/codec/framed_read.rs defaults max_header_list_size to 16 MB. The HPACK decoder (src/frame/headers.rs, HeaderBlock::load) continues decoding past the limit (to keep HPACK state consistent) but sets is_over_size = true; the stream layer then rejects the frame with REFUSED_STREAM or PROTOCOL_ERROR. This justifies impl-parser and parser-impl-safe and protocol-impl-safe.
CONTINUATION flooding: src/codec/framed_read.rs tracks continuation_frames_count per partial header block and enforces max_continuation_frames (derived from header and frame size limits, minimum 5). Exceeding the limit closes the connection with ENHANCE_YOUR_CALM "too_many_continuations". Added in 0.4.4.
Rapid Reset (CVE-2023-44487): Two separate counters mitigate this. num_remote_reset_streams (cap: DEFAULT_REMOTE_RESET_STREAM_MAX = 20) counts remotely reset pending-accept streams; exceeding it closes the connection with ENHANCE_YOUR_CALM "too_many_resets" (src/proto/streams/recv.rs:886-899). num_local_error_reset_streams (cap: DEFAULT_LOCAL_RESET_COUNT_MAX = 1024) counts library-initiated RST_STREAM frames per connection lifetime; exceeding it triggers GOAWAY with ENHANCE_YOUR_CALM "too_many_internal_resets" (src/proto/streams/streams.rs). Both are enabled by default and configurable via builder methods.
Flow-control accounting uses a signed Window(i32) type with checked arithmetic throughout (src/proto/streams/flow_control.rs). inc_window additionally bounds the value to MAX_WINDOW_SIZE = 2^31 - 1. Receiving data beyond the window triggers FLOW_CONTROL_ERROR at stream or connection level. impl-protocol is true: the crate implements the HTTP/2 framing, flow-control, stream state machine, and HPACK compression protocols.
The HPACK integer decoder (src/hpack/decoder.rs:391-448) limits multi-byte integers to 5 octets and returns IntegerOverflow if exceeded, preventing integer-overflow attacks from malformed HPACK streams.
The test suite includes in-crate unit tests (40 #[test] assertions), an integration test workspace at tests/h2-tests/, quickcheck property tests in dev-dependencies, and a LibFuzzer fuzz harness at tests/h2-fuzz/. This justifies has-unit-tests, has-integration-tests, has-fuzz-tests, has-property-tests, parser-impl-tested, and protocol-impl-tested.
parser-impl-correct and protocol-impl-correct were not evaluated against the full RFC 9113 conformance suite; the HPACK fixture tests (src/hpack/test/fixture.rs) do cover the published HPACK spec test vectors. unsafe-tested: the single unsafe block is trivially correct and has been present without incident since the crate's creation; no miri or sanitizer run was performed during this audit.
No findings were recorded.
Conclusion
The codebase has one unsafe block with a valid and documented invariant. All known HTTP/2 DoS vectors reviewed in this audit — HPACK bomb, CONTINUATION flooding, Rapid Reset — have explicit mitigations active by default. Flow-control arithmetic is performed with checked operations that return protocol errors on overflow. The test suite includes fuzz tests and property-based tests covering the HPACK decoder, which is the highest-risk parsing component.