1

Is there any way to validate IPv6 URLs?

http://[2001:630:181:35::83]/index.php should be a valid URL

but PHP's filter_var function will return false

How can I add support for IPv6 addresses?

user3896501
  • 2,987
  • 1
  • 22
  • 25
  • possible duplicate of [regular expression for IPv6 addresses](http://stackoverflow.com/questions/14638711/regular-expression-for-ipv6-addresses) – Marcin Orlowski Aug 15 '14 at 09:56
  • 1
    @Marcin Not a valid duplicate for this one. – deceze Aug 15 '14 at 09:59
  • 2
    Using `filter_var()`, you can't validate IPv6 URLs. This is not really clear in the documentation. After some research I found the problem: It is stated in [php docs](http://php.net/manual/en/filter.filters.validate.php) that `FILTER_VALIDATE_URL` validates the input according to [RFC2396](http://www.faqs.org/rfcs/rfc2396.html). When scrolling down in that RFC to `3.2.2. Server-based Naming Authority` it states the following *The host is a domain name of a network host, or its IPv4 address as a set of four decimal digit groups separated by ".". **Literal IPv6 addresses are not supported.*** – HamZa Aug 15 '14 at 11:30
  • 2
    This means you either need to change the source code of php itself in [**logical_filters.c**](http://lxr.php.net/xref/PHP_5_6/ext/filter/logical_filters.c) and probably also in [**sanitizing_filters.c**](http://lxr.php.net/xref/PHP_5_6/ext/filter/sanitizing_filters.c) but I guess that's not an option. I suggest to use a custom regex. It should be somewhere on SO I guess... [This mighe be a good start](http://stackoverflow.com/a/4713820) – HamZa Aug 15 '14 at 11:31
  • 1
    My article: [Regular Expression URI Validation](http://www.jmrware.com/articles/2009/uri_regexp/URI_regex.html) may be helpful here. It includes regexes for IPv6 as well as all the other URI components specified in [RFC-3986](http://tools.ietf.org/html/rfc3986). – ridgerunner Aug 15 '14 at 13:36
  • @ridgerunner How to compile your regex to usable in PHP? I am not really understand which part is for matching URLs – user3896501 Aug 15 '14 at 13:57

1 Answers1

0

I made a workaround using a combination of FILTER_VALIDATE_URL and FILTER_VALIDATE_IP with FILTER_FLAG_IPV6. This is a regex free solution:

function validate($url)
{
    # 1. We validate the url
    if (false === filter_var($url, FILTER_VALIDATE_URL)) {

        # 2. Consider the posibility of an IPV6 host
        $host = parse_url($url, PHP_URL_HOST);
        $ipv6 = trim($host, '[]'); // trim potential enclosing tags for IPV6

        # 3. Validate IPV6
        if (false === filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            return false;
        } else {

            # 4. We have a valid IPV6, replace it with a generic host url for further validation purposes
            $newUrl = str_replace($host, 'www.someUrl.com', $url);

            # 5. We validate the new url
            if (false === filter_var($newUrl, FILTER_VALIDATE_URL)) {
                return false;
            }
        }
    }

    return true;
}

NOTE: parse_url() doesn't always fail if the url is not valid, therefore you can't replace the host blindly, prior to validation, you might miss something wrong in the host itself. So... validating a second time after changing the host seems to be the right way to do it in case of IPV6.

ntt
  • 426
  • 1
  • 4
  • 9