fix(node): parse absolute-form request targets - #85
Merged
Conversation
@standardserver/aws-lambda
@standardserver/core
@standardserver/fastify
@standardserver/fetch
@standardserver/node
@standardserver/peer
@standardserver/shared
commit: |
Co-authored-by: Xia Chao <236466140+bun-unsafe@users.noreply.github.com>
dinwwwh
force-pushed
the
fix/node-absolute-form-request-target
branch
from
September 5, 2026 03:56
ea692c5 to
e67d542
Compare
Contributor
Merging this PR will not alter performance
Comparing Footnotes
|
Contributor
There was a problem hiding this comment.
ℹ️ Minor suggestions only — the absolute-form parsing fix is correct and the new test coverage genuinely discriminates against the old behavior.
Reviewed changes — initial review of PR #85 (commit e67d542 vs base f13e415).
packages/node/src/url.ts—toStandardUrlnow short-circuits origin-form targets unchanged and reduces absolute-form (and otherURL-parseable) targets topathname + search + hashvianew URL(url, 'http://localhost')+ the Fetch adapter'stoStandardUrl, falling back to/${url}on parse errors.packages/node/src/url.test.ts— expanded from one case to sevenitblocks covering origin-form (incl.*),originalUrlprecedence with absolute-form, absolute-form collapsing, non-http schemes, relative-path fallbacks, malicious/malformed input, and a raw-socket round-trip against a livenode:httpserver that would have failed on the old/${url}prefixing.
ℹ️ Nitpicks
- url.ts:9-14 — the
startsWith('/')early-return ordering is load-bearing: it is the only thing keeping an origin-form target like//evil.com/pingfrom being host-resolved to/pingbynew URL. A one-line comment recording that this ordering is intentional (plus why the'http://localhost'base exists only to coerce fallback strings) would stop a future cleanup from silently reintroducing the hostization the malicious-input tests guard against.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

HTTP/1.1 clients that treat the server as a forward proxy (
curl -x <server> <url>,HTTP_PROXYpointed at the app, some intermediaries) send the request target in absolute-form,GET http://host:port/ping HTTP/1.1, and Node hands that string through asreq.urlverbatim.toStandardUrlprefixed it with/, so routers saw/http://host:port/pingand answered 404. Absolute-form targets are now parsed withURLand reduced to pathname + search + hash through the Fetch adapter'stoStandardUrl, so the Node and Fetch adapters yield the sameStandardUrlfor the same request.Supersedes #81. Thanks @javascript-unsafe for the report and the initial fix.
Fixes
GET http://127.0.0.1:3000/ping?x=1against a realnode:httpserver now yields/ping?x=1. The Fastify adapter inherits this throughreq.raw.//evil.com/xstays a path rather than a host.http://,http://[::1, an out-of-range port) keeps the previous/${url}fallback instead of throwing.Testing
originalUrlprecedence, absolute-form, normalization parity with the Fetch adapter, non-http schemes, and malicious or malformed input ported from oRPC'sstandard-server-nodetests.node:httpserver.tsc -bpass.