Skip to content

Instantly share code, notes, and snippets.

@pcaversaccio
Last active January 18, 2026 14:28
Show Gist options
  • Select an option

  • Save pcaversaccio/9bda7737012e98b1c3935eeee95031a3 to your computer and use it in GitHub Desktop.

Select an option

Save pcaversaccio/9bda7737012e98b1c3935eeee95031a3 to your computer and use it in GitHub Desktop.
Protective wrappers for `curl`/`wget` that prevent homograph/IDN attacks by blocking URLs containing non-ASCII characters or Punycode domains.
#!/usr/bin/env bash
set -Eeuo pipefail
RED=$'\033[1;31m'
YELLOW=$'\033[1;33m'
RESET=$'\033[0m'
for arg in "$@"; do
# Reject any non-ASCII byte.
if LC_ALL=C printf "%s" "$arg" | grep -q "[^ -~]"; then
printf "${RED}BLOCKED:${RESET} Non-ASCII characters detected!\n\n" >&2
visual=$(LC_ALL=C printf "%s" "$arg" | sed "s/[^ -~]/${RED}●${RESET}/g")
printf " Visual: %b\n" "$visual" >&2
printf " Escaped: ${YELLOW}%q${RESET}\n\n" "$arg" >&2
printf " ${YELLOW}Suspicious bytes:${RESET}\n" >&2
LC_ALL=C printf "%s" "$arg" \
| grep -o "[^ -~]" \
| xxd -g1 \
| sed "s/^/ /" >&2
exit 1
fi
# Reject Punycode (case-insensitive).
if [[ "$arg" =~ [Xx][Nn]-- ]]; then
printf "${RED}BLOCKED:${RESET} Punycode domain detected!\n\n" >&2
highlighted=${arg//xn--/${RED}xn--${RESET}}
highlighted=${highlighted//Xn--/${RED}Xn--${RESET}}
highlighted=${highlighted//XN--/${RED}XN--${RESET}}
highlighted=${highlighted//xN--/${RED}xN--${RESET}}
printf " URL: %b\n\n" "$highlighted" >&2
exit 1
fi
done
exec /usr/bin/curl "$@"
#!/usr/bin/env bash
set -Eeuo pipefail
RED=$'\033[1;31m'
YELLOW=$'\033[1;33m'
RESET=$'\033[0m'
for arg in "$@"; do
# Reject any non-ASCII byte.
if LC_ALL=C printf "%s" "$arg" | grep -q "[^ -~]"; then
printf "${RED}BLOCKED:${RESET} Non-ASCII characters detected!\n\n" >&2
visual=$(LC_ALL=C printf "%s" "$arg" | sed "s/[^ -~]/${RED}●${RESET}/g")
printf " Visual: %b\n" "$visual" >&2
printf " Escaped: ${YELLOW}%q${RESET}\n\n" "$arg" >&2
printf " ${YELLOW}Suspicious bytes:${RESET}\n" >&2
LC_ALL=C printf "%s" "$arg" \
| grep -o "[^ -~]" \
| xxd -g1 \
| sed "s/^/ /" >&2
exit 1
fi
# Reject Punycode (case-insensitive).
if [[ "$arg" =~ [Xx][Nn]-- ]]; then
printf "${RED}BLOCKED:${RESET} Punycode domain detected!\n\n" >&2
highlighted=${arg//xn--/${RED}xn--${RESET}}
highlighted=${highlighted//Xn--/${RED}Xn--${RESET}}
highlighted=${highlighted//XN--/${RED}XN--${RESET}}
highlighted=${highlighted//xN--/${RED}xN--${RESET}}
printf " URL: %b\n\n" "$highlighted" >&2
exit 1
fi
done
exec /usr/bin/wget "$@"
@pcaversaccio
Copy link
Author

pcaversaccio commented Jan 16, 2026

Installation

~$ sudo tee /usr/local/bin/curl > /dev/null <<"EOF"
#!/usr/bin/env bash
set -Eeuo pipefail

RED=$'\033[1;31m'
YELLOW=$'\033[1;33m'
RESET=$'\033[0m'

for arg in "$@"; do
    # Reject any non-ASCII byte.
    if LC_ALL=C printf "%s" "$arg" | grep -q "[^ -~]"; then
        printf "${RED}BLOCKED:${RESET} Non-ASCII characters detected!\n\n" >&2
        visual=$(LC_ALL=C printf "%s" "$arg" | sed "s/[^ -~]/${RED}●${RESET}/g")
        printf "  Visual: %b\n" "$visual" >&2
        printf "  Escaped: ${YELLOW}%q${RESET}\n\n" "$arg" >&2
        printf "  ${YELLOW}Suspicious bytes:${RESET}\n" >&2
        LC_ALL=C printf "%s" "$arg" \
          | grep -o "[^ -~]" \
          | xxd -g1 \
          | sed "s/^/    /" >&2
        exit 1
    fi

    # Reject Punycode (case-insensitive).
    if [[ "$arg" =~ [Xx][Nn]-- ]]; then
        printf "${RED}BLOCKED:${RESET} Punycode domain detected!\n\n" >&2
        highlighted=${arg//xn--/${RED}xn--${RESET}}
        highlighted=${highlighted//Xn--/${RED}Xn--${RESET}}
        highlighted=${highlighted//XN--/${RED}XN--${RESET}}
        highlighted=${highlighted//xN--/${RED}xN--${RESET}}
        printf "  URL: %b\n\n" "$highlighted" >&2
        exit 1
    fi
done
exec /usr/bin/curl "$@"
EOF

~$ sudo chmod +x /usr/local/bin/curl
~$ sudo tee /usr/local/bin/wget > /dev/null <<"EOF"
#!/usr/bin/env bash
set -Eeuo pipefail

RED=$'\033[1;31m'
YELLOW=$'\033[1;33m'
RESET=$'\033[0m'

for arg in "$@"; do
    # Reject any non-ASCII byte.
    if LC_ALL=C printf "%s" "$arg" | grep -q "[^ -~]"; then
        printf "${RED}BLOCKED:${RESET} Non-ASCII characters detected!\n\n" >&2
        visual=$(LC_ALL=C printf "%s" "$arg" | sed "s/[^ -~]/${RED}●${RESET}/g")
        printf "  Visual: %b\n" "$visual" >&2
        printf "  Escaped: ${YELLOW}%q${RESET}\n\n" "$arg" >&2
        printf "  ${YELLOW}Suspicious bytes:${RESET}\n" >&2
        LC_ALL=C printf "%s" "$arg" \
          | grep -o "[^ -~]" \
          | xxd -g1 \
          | sed "s/^/    /" >&2
        exit 1
    fi

    # Reject Punycode (case-insensitive).
    if [[ "$arg" =~ [Xx][Nn]-- ]]; then
        printf "${RED}BLOCKED:${RESET} Punycode domain detected!\n\n" >&2
        highlighted=${arg//xn--/${RED}xn--${RESET}}
        highlighted=${highlighted//Xn--/${RED}Xn--${RESET}}
        highlighted=${highlighted//XN--/${RED}XN--${RESET}}
        highlighted=${highlighted//xN--/${RED}xN--${RESET}}
        printf "  URL: %b\n\n" "$highlighted" >&2
        exit 1
    fi
done
exec /usr/bin/wget "$@"
EOF

~$ sudo chmod +x /usr/local/bin/wget

Verification

Verify the installation locations:

~$ which curl
~$ which wget

Verify the files exist and are executable:

~$ ls -la /usr/local/bin/curl
~$ ls -la /usr/local/bin/wget

Verify they're Bash scripts:

~$ head -1 /usr/local/bin/curl
~$ head -1 /usr/local/bin/wget

Test non-ASCII blocking:

~$ curl https://foundry.paradіgm.xyz
~$ wget https://foundry.paradіgm.xyz

Test Punycode blocking:

~$ curl https://xn--test.example.com
~$ wget https://xn--test.example.com

Test legitimate URLs still work:

~$ curl -I https://google.com
~$ wget -O- https://icanhazip.com

Verify the real binaries are still accessible:

~$ /usr/bin/curl --version
~$ /usr/bin/wget --version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment