Skip to content

trust proxy is enabled for every hop, so req.ip, req.hostname and req.protocol follow client-supplied X-Forwarded-* values #807

Open

Description

@cybrdude

Where. src/server.ts getServer() calls app.enable('trust proxy') (line 98 in 5.0.5; the line dates from the initial commit). In Express that is trust proxy: true: every X-Forwarded-For entry is trusted, so req.ip is the left-most entry, which is whatever the client sent before the request reached Cloud Run. req.ips returns the whole list, and req.hostname / req.protocol follow X-Forwarded-Host / X-Forwarded-Proto the same way (https://expressjs.com/en/guide/behind-proxies.html).

Why it matters. Function code commonly keys rate limits, allowlists and audit logs on req.ip (the Cloud Functions rate-limiting tutorial in GoogleCloudPlatform/community does exactly that). With the current default those keys are client-chosen. Cloud Run places one proxy in front of the function and adds the address it accepted the connection from as the last X-Forwarded-For entry, so one trusted hop is the setting that yields that address; GoogleCloudPlatform/nodejs-docs-samples#3583 reached the same conclusion for the Cloud Run samples.

Reproduce. Run any HTTP function under the framework and send a request whose X-Forwarded-For already contains an address; req.ip reports that address rather than the connecting peer. With app.set('trust proxy', 1) it reports the last entry.

Proposed change. Add a --trust-proxy / TRUST_PROXY option (hop count, true, false, or an address list), pass it to Express, default it to 1, and document it in the README options table with a note to raise it when another proxy or load balancer sits in front of Cloud Run. Deployments that relied on true can set TRUST_PROXY=true to keep the previous behavior. PR with tests follows.

Reported to the Google Cloud VRP as well (b/576218448); filing here because the behavior is standard Express semantics and the fix is a configuration default.

Activity

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

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions