Possible problem with IP validation in the installer

Of topic:

I just searched through the code of the installer and found a bug (i think).

The IP check you mentioned is there (valid_ip) but the problem i see is this:

if [[ ${ip} =~ [1]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then

This checks if the IP has the numbers 0-9 in it which can go up to 3 digits. The problem is that IP's can only go up to 255.255.255.255, this check would let a IP such as 999.999.999.999 count as valid.

The code i mean.

Please correct me if i'm wrong.


  1. 0-9 ↩︎

You're not wrong, it's mostly for formatting of the numbers, it's rather difficult to actually check for a valid IP (IPv4), very difficult for v6 in hex notation.

# Test an IP address for validity:
# Usage:
#      valid_ip IP_ADDRESS
#      if [[ $? -eq 0 ]]; then echo good; else echo bad; fi
#   OR
#      if valid_ip IP_ADDRESS; then echo good; else echo bad; fi
#
function valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

http://www.linuxjournal.com/content/validating-ip-address-bash-script

We could also try to dig something from the provided IP. If there is no result - well then that IP might be valid in principle, but still unusable?

I found a solution that works.

if [[ $PIHOLE_DNS_1 =~ .*:.* ]]; then
        dns1=IPv6
else
        dns1=IPv4
fi

if [[ $PIHOLE_DNS_2 =~ .*:.*  ]]; then
        dns2=IPv6
else
        dns2=IPv4
fi

lookupDNS1="$(nslookup -retry=1 -timeout=5 google.de $PIHOLE_DNS_1)"

if [[ $lookupDNS1 == *";; connection timed out; no servers could be reached"* ]]; then
        echo "Your first DNS server ($dns1) isn't working!"
else
        echo "Your first DNS server ($dns1) is working!"
fi

lookupDNS2="$(nslookup -retry=1 -timeout=5 google.de $PIHOLE_DNS_2)"

if [[ $lookupDNS2 == *";; connection timed out; no servers could be reached"* ]]; then
        echo "Your second DNS server ($dns2) isn't working!"
else
        echo "Your second DNS server ($dns2) is working!"
fi

This can also be used to see if a IPv6 connection is avaliable.

ipv6test="$(nslookup -retry=1 -timeout=5 google.de 2001:4860:4860::8888)"

if [[ $ipv6test == *";; connection timed out; no servers could be reached"*  ]]; then
        echo "You don't have a IPv6 connection!"
else
        echo "You have a Ipv6 connection!"
fi

Okay, this approach needs some more protection about injection of bad code through the entered variables. What is the advantage of using nslookup? We know that dig is always available.

Could you give me a example of bad code that could be injected? I'm not sure how this can be used to do something bad.

I don't think that there is a advantage of using nslookup, i just had the idea to use it.

You are root at this point. Not tested, just thinking aloud:

PIHOLE_DNS_1=";rm -rf /etc/*"

would evaluate to:

nslookup -retry=1 -timeout=5 google.de ;rm -rf /etc/*

i.e.

nslookup -retry=1 -timeout=5 google.de
rm -rf /etc/*
1 Like