Files
nvm/test/fast/Unit tests/nvm_url_origin
T
Jordan Harband e780535240 [Fix] nvm_download: with GNU Wget, follow only same-origin redirects when sending $NVM_AUTH_HEADER
curl 7.58.0 and later drop a custom Authorization header when a redirect leads to another host,
but wget sends `--header` along to every redirect target,
so on a machine without curl,
a mirror that redirected elsewhere handed the credential to that other host.

When a header is sent with GNU Wget,
run it with `--max-redirect=0`.
When it then exits with 8
(an HTTP error, which includes a redirect it did not follow),
read the `Location` with one more request,
and re-request it only if it keeps the same scheme,
host, and port, up to 20 times.
A redirect to another origin,
including a downgrade to `http`,
fails with exit code 8 and an error that names the URL nvm requested and suggests curl.
`--max-redirect` is not a BusyBox wget option,
so other wgets are invoked as before;
the README says so

Discovered by Anthropic's OSS Scanner, as ANT-2026-PKUZHTT3; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00

39 lines
1.6 KiB
Bash
Executable File

#!/bin/sh
die () { echo "$@" ; exit 1; }
\. ../../../nvm.sh
check() {
ACTUAL="$(nvm_url_origin "${1}")"
[ "${ACTUAL}" = "${2}" ] || die "nvm_url_origin '${1}': expected >${2}<, got >${ACTUAL}<"
}
# the path is dropped
check 'https://nodejs.org/dist' 'https://nodejs.org'
check 'https://nodejs.org/dist/v20.0.0/node-v20.0.0.tar.xz' 'https://nodejs.org'
check 'https://nodejs.org/' 'https://nodejs.org'
check 'http://mirror.example//dist' 'http://mirror.example'
# a URL with no path is its own origin
check 'https://nodejs.org' 'https://nodejs.org'
# the scheme and port are kept, so they take part in the comparison
check 'http://nodejs.org/dist' 'http://nodejs.org'
check 'http://127.0.0.1:8080/dist/target' 'http://127.0.0.1:8080'
check 'https://nodejs.org:443/dist' 'https://nodejs.org:443'
check 'https://[::1]:8080/dist' 'https://[::1]:8080'
# the authority runs to the first `/` after the scheme, so a host spelled
# differently later in the URL does not change it
check 'https://mirror.example/http://elsewhere.example/dist' 'https://mirror.example'
check 'https://mirror.example/@elsewhere.example/dist' 'https://mirror.example'
# userinfo is part of the authority
check 'https://user:pw@mirror.example/dist' 'https://user:pw@mirror.example'
# anything before the first `/` is kept as is, so a lookalike authority differs
check 'https://mirror.example@elsewhere.example/dist' 'https://mirror.example@elsewhere.example'
check 'https://mirror.example.elsewhere.example/dist' 'https://mirror.example.elsewhere.example'
check 'https://mirror.example?@elsewhere.example/dist' 'https://mirror.example?@elsewhere.example'