16

I have an application which must warn the user upon use of localhost, 127.0.0.1, ::1, or any loopback address (the target host is used for a database-to-database connection not necessarily inside of the environment of the application). This is made complicated because addresses like the following...

  • 127.1
  • 127.0.01
  • 127.0000.0000.1
  • 127.0.0.254
  • 127.63.31.15
  • 127.255.255.254
  • 0::1
  • 0000::0001
  • 0000:0:0000::01
  • 0000:0000:0000:0000:0000:0000:0000:0001

...will parse properly by the consuming code, and will resolve to loopback.

What is a regular expression which will match any permutation of the IPv4 and IPv6 loopback addresses?

Tullo_x86
  • 2,573
  • 25
  • 27
  • 1
    A common security guideline is to enumerate the cases you do want to allow, rather than try to enumerate the disallowed cases. If you can restrict to standard IPv4 notation (four dot-separated octets), excluding 127/8 is then easy. – tripleee Dec 08 '11 at 06:31
  • That's a good rule. This particular issue isn't security-related (just a warning for "beware: your localhost may vary from the server's"), but I see the principle behind it. – Tullo_x86 Dec 08 '11 at 22:32

3 Answers3

32

After a short time fiddling around in RegexBuddy (which is a truly magnificent tool for test-driven RegEx construction), I have come up with this:

^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$

This RegEx matches

The string "localhost"

  • localhost
  • LOCALHOST

These permutations of the IPv4 loopback address

  • 127.0.0.1
  • 127.0.0.001
  • 127.0.00.1
  • 127.00.0.1
  • 127.000.000.001
  • 127.0000.0000.1
  • 127.0.01
  • 127.1
  • 127.001
  • 127.0.0.254
  • 127.63.31.15
  • 127.255.255.254

These permutations of the IPv6 loopback address

  • 0:0:0:0:0:0:0:1
  • 0000:0000:0000:0000:0000:0000:0000:0001
  • ::1
  • 0::1
  • 0:0:0::1
  • 0000::0001
  • 0000:0:0000::0001
  • 0000:0:0000::1
  • 0::0:1

This RegEx does not match

A valid server name

  • servername
  • subdomain.domain.tld

These valid IPv4 addresses

  • 192.168.0.1
  • 10.1.1.123

These valid IPv6 addresses

  • 0001::1
  • dead:beef::1
  • ::dead:beef:1
Tullo_x86
  • 2,573
  • 25
  • 27
4

If you're not concerned with proving whether the address is valid, then this should work:

/^(127\.[\d.]+|[0:]+1|localhost)$/i
phatfingers
  • 9,770
  • 3
  • 30
  • 44
  • This matches the common case of `127.0.0.1`, as well as all of my IPv6 test cases, but won't match `127.0.0.001`, `127.00.0.1` or `127.63.31.15`, among others. However, changing it to `^(127(\.\d+){1,3}|[0:]+1|localhost)$` makes it as effective as mine, and much more concise. – Tullo_x86 Dec 08 '11 at 05:27
  • Good catch. I'll update it accordingly to make it correct in case anyone copies it. I like your use of non-captures, and your set of test cases. – phatfingers Dec 08 '11 at 07:38
  • Thanks. I much prefer your RegEx for its brevity - especially since I only need to *reject* loopback addresses, not parse or validate it. – Tullo_x86 Dec 08 '11 at 22:24
  • don't forget "0.0.0.0": ^(127(\.\d+){1,3}|[0:]+1|localhost|0\.0\.0\.0)$ – konsumer Sep 24 '14 at 22:29
  • 1
    That's not a loopback address. To quote Wikipedia, 0.0.0.0 is a non-routable meta-address used to designate an invalid, unknown or non applicable target. – phatfingers Sep 30 '14 at 22:33
1

I created this regex for capturing different permutations of IPv6 loopback addresses:

(0{0,4}:{1,2}){1,7}(0{0,3}1)

i tested it on the following addresses:

  • 0:0:0:0:0:0:0:1
  • 0000:0000:0000:0000:0000:0000:0000:0001
  • ::1
  • 0::1
  • 0:0:0::1
  • 0:0:0000::1
  • 0000:0:00::0001
  • 0000::0001
  • 0000:0:0000::0001
  • 0000:0:0000::1
  • 0::0:1

and it captured them all.

you can test it on http://regexr.com/3bqpm

Fouad
  • 11
  • 1