Skip to content

request.protocol differs across Node, Bun and uWS runtimes #3074

Open

Description

@kriszyp

request.protocol is computed three different ways depending on which HTTP runtime serves the request, so an app behind a proxy can see a different scheme for the same client connection.

Where (server/serverHelpers/Request.ts on main)

Runtime Line Returns https when
Node ~116 the socket is TLS, or the PROXY v2 header carries the SSL TLV. X-Forwarded-Proto is ignored.
Bun ~305 the listener is secure. No X-Forwarded-Proto, no TLV.
uWS ~420 X-Forwarded-Proto is present (its raw value is returned), else the listener is secure.

Effect

  • Behind a proxy that sends only X-Forwarded-Proto: https, Node and Bun report http and uWS reports https. Scheme-dependent app logic (secure cookies, redirect targets, absolute URL construction) changes with the runtime.
  • On uWS the header value is returned unvalidated: a value like https, http or any other string passes through, and a client can set it if the fronting proxy does not overwrite the header.

The documentation already notes that the runtimes differ (reference/http/api.md), which is the right interim state.

Decision needed

One contract for all three runtimes. For example: trust the PROXY v2 TLV and the listener's secure flag everywhere, and honor X-Forwarded-Proto only from a trusted proxy hop, normalized to http/https.

— Claude Opus 5.5 (finding-triage)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    P2

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions