fix(url-guard): restore the SSRF guard on bash 3.2
`${1,,}` is bash 4.0+. macOS ships bash 3.2 as /bin/bash, where it raises
"bad substitution"; the subshell then exited 1 — read as "not local" — so
`url-guard.sh host` returned rc 0 for localhost, 127.x, 10.x, 192.168.x,
172.16-31.x, 169.254.169.254 and metadata.google.internal. The guard failed
OPEN on every Mac, and url-guard.test.sh recorded it as 13 "got[0] want[2]".
`shopt -s nocasematch` (bash 3.1+) keeps both the ASCII-only folding that
LC_ALL=C gives and the no-fork property the lowercase expansion had.
Verified on /bin/bash 3.2: the ten local/private/metadata targets now return
rc 2 (case-folded variants included), legitimate hosts still rc 0.
This commit is contained in:
+8
-3
@@ -41,9 +41,14 @@ _rest_charset_ok() ( LC_ALL=C; case "$1" in
|
||||
# Literal local/private/metadata targets. This is a LITERAL check, not a DNS
|
||||
# one: it stops the obvious, not a hostname that resolves inward.
|
||||
_host_is_local() ( LC_ALL=C
|
||||
# ${1,,} not tr: no fork, and no SC2018/SC2019 noise. Safe because the
|
||||
# charset guard has already run — the string is [A-Za-z0-9.-] by here.
|
||||
case "${1,,}" in
|
||||
# `nocasematch` not ${1,,}: the lowercase expansion is bash 4.0+, and macOS
|
||||
# ships bash 3.2 as /bin/bash — there it raised "bad substitution" and the
|
||||
# subshell exited 1, i.e. "not local", so EVERY local/private/metadata host
|
||||
# was allowed through. Keeps the no-fork property the lowercase form had.
|
||||
# Safe because the charset guard has already run — the string is
|
||||
# [A-Za-z0-9.-] by here, and LC_ALL=C keeps the folding ASCII-only.
|
||||
shopt -s nocasematch
|
||||
case "$1" in
|
||||
localhost|*.localhost|*.local|0.0.0.0|broadcasthost) exit 0 ;;
|
||||
127.*|10.*|169.254.*|192.168.*) exit 0 ;;
|
||||
172.1[6-9].*|172.2[0-9].*|172.3[01].*) exit 0 ;;
|
||||
|
||||
Reference in New Issue
Block a user