Skip to content

Tracking: runtime robustness & numeric/security hardening #45

Description

@aaylward

Tracking issue from a whole-project review. Grouped runtime findings; the UB-class timestamp items are broken out in #42. Each can graduate to its own issue when picked up.

  • Beast client accepts unbounded response bodies (OOM DoS). beast_transport.cc:473 sets parser.body_limit(boost::none); the socket client caps at 64 MiB (socket_transport.cc:85) but the production Beast client does not. A malicious/malfunctioning server (or MITM on verify_peer=false) streams an endless body into a std::string.
  • IPv6 endpoint literals parsed incorrectly. uri.cc:167 uses authority.rfind(':') to split host/port: http://[::1]/ splits inside the address; http://[::1]:8080/ keeps brackets in host and getaddrinfo rejects it. IPv6 endpoints never connect.
  • CRLF/header injection on the socket transport. socket_transport.cc:203-208 (client) and :314-319 (server) concatenate header names/values with no CR/LF validation → response splitting when a handler copies untrusted input into a header value.
  • Retries ignore idempotency and have no retry budget. retry.cc:58-66 retries any transient failure regardless of HTTP method and with no token bucket → duplicate non-idempotent POSTs on a timed-out-but-succeeded request; retry storms amplify a cluster-wide 503.
  • Utf8CodePointCount miscounts invalid UTF-8, weakening @length. text.cc:5-12 counts every non-10xxxxxx byte; lone continuation bytes / truncated sequences let an attacker slip past minLength/maxLength.
  • Unbounded encode-side recursion. cbor.cc:76 / json.cc:13 recurse without a depth guard when encoding a deeply nested in-memory Document (decode paths are guarded — CBOR 64, JSON 512). Stack overflow, asymmetric with decode.
  • RetryDelay overflows before clamping. retry.cc:21-22 computes initial_backoff * (1 << exponent) before std::min(max_backoff, …); a caller-configured large initial_backoff overflows int64.
  • Unknown CBOR tags silently unwrapped. cbor.cc:294 returns the inner value for any non-tag-1 tag, so bignum/decimal (tags 2/3/4) are misdecoded as their raw content type instead of erroring.
  • Leap seconds rejected. timestamp.cc:37-38 requires second <= 59, so a valid RFC3339 :60 is treated as malformed.
  • Server request-line target truncated at first space. socket_transport.cc:297 silently drops anything after a second space rather than rejecting the malformed request line.
  • Auth middleware checks only the first matching header and demands exactly one space. middleware.cc:52-64,78 → spurious 401s on duplicated auth headers or tab/multi-space separators.
  • API footgun (LOW): as_x() / Outcome::operator* throw std::bad_variant_access on precondition violation in an exception-free API (document.h:70-79, outcome.h:32-44) → std::terminate instead of a diagnosable error. Also Document(1) != Document(1.0) and NaN-documents never self-compare (document.h:94). (Consumer-facing ergonomics for this are also in the adoption tracking issue.)

Related top-tier: #42.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions