mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-06-05 13:57:08 +08:00
[Fix] nvm_get_checksum: pass the tarball name to awk as data, not program text
The awk program string-interpolated the slug
(which embeds the untrusted, mirror-supplied version)
into its source, so a crafted version such as
`v1"==$2){system("touch${IFS}/tmp/x")}#`
was executed by awk's `system()`.
Pass the value via `-v tarball=...` so awk treats it as data and never as code.
See GHSA-3c52-35h2-gfmm
(a second injection sink fed by the same untrusted version field that `nvm_download`'s eval was; the source-install path reaches this during a normal `nvm install <version>`).
This commit is contained in:
2
nvm.sh
2
nvm.sh
@@ -1927,7 +1927,7 @@ nvm_get_checksum() {
|
||||
SHASUMS_URL="${MIRROR}/${3}/SHASUMS.txt"
|
||||
fi
|
||||
|
||||
nvm_download -L -s "${SHASUMS_URL}" -o - | command awk "{ if (\"${4}.${5}\" == \$2) print \$1}"
|
||||
nvm_download -L -s "${SHASUMS_URL}" -o - | command awk -v tarball="${4}.${5}" '{ if (tarball == $2) print $1 }'
|
||||
}
|
||||
|
||||
nvm_print_versions() {
|
||||
|
||||
28
test/fast/Unit tests/nvm_get_checksum awk injection
Executable file
28
test/fast/Unit tests/nvm_get_checksum awk injection
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
WORK="${TMPDIR:-/tmp}/nvm_get_checksum_awk.$$"
|
||||
PROOF="${WORK}/PWNED"
|
||||
|
||||
cleanup () {
|
||||
unset -f die cleanup nvm_download
|
||||
rm -rf "${WORK}"
|
||||
}
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
|
||||
\. ../../../nvm.sh
|
||||
|
||||
mkdir -p "${WORK}"
|
||||
|
||||
# GHSA-3c52-35h2-gfmm: nvm_get_checksum must treat the (untrusted, version-derived)
|
||||
# slug as awk data, never as awk program text.
|
||||
# given a crafted slug carrying an unconditional awk system() action
|
||||
# and a mock that supplies one SHASUMS record (so such an action would fire)
|
||||
nvm_download () { printf 'deadbeef sometarball\n'; }
|
||||
# when nvm_get_checksum runs with that slug as its 4th argument
|
||||
rm -f "${PROOF}"
|
||||
nvm_get_checksum node std v1 'x" == $2) print $1} {system("touch${IFS}'"$PROOF"'")} #' tar.gz >/dev/null 2>&1
|
||||
# then the injected awk code must not execute
|
||||
[ ! -e "${PROOF}" ] || die 'awk injection fires in nvm_get_checksum (slug interpolated into awk program text)'
|
||||
|
||||
cleanup
|
||||
echo 'nvm_get_checksum awk injection: passed'
|
||||
Reference in New Issue
Block a user