I have many projects with functionalities relying on IP addresses provided by $_SERVER['REMOTE_ADDR]
, $_SERVER['HTTP_X_FORWARDED_FOR']
, and $_SERVER['CLIENT_IP']
.
IPV4 addresses are easy to match since we always receive them in the same format: 4 integers without the leading 0s, separated by a dot .
.
Whereas IPV6 addresses can be compressed. Ex: FF01:0:0:0:0:0:0:101 -> FF01::101
I've been researching this issue but haven't found anything relevant, so I'm asking for your experience. Is $_SERVER['REMOTE_ADDR]
using a standard? Is it safe to assume that it will always be received as compressed or uncompressed?
Or should I compress all my IPV6 string before I try to try test them?
Note:
Ideally I would like to handle IPV6 addresses as strings rather than binary structure, to improve readability in Databases / Source code and allow easier IP range matching.
The IPv6 address size is 128 bits. The preferred IPv6 address representation is: x:x:x:x:x:x:x:x , where each x is the hexadecimal values of the eight 16-bit pieces of the address. IPv6 addresses range from 0000:0000:0000:0000:0000:0000:0000:0000 to ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff .
Double colon. Specify IPv6 addresses by using double colons ( :: ) in place of a series of zeros. For example, IPv6 address ff06:0:0:0:0:0:0:c3 can be written as ff06::c3 . Double colons can be used only once in an IP address.
Yes, it's safe. It is the source IP of the TCP connection and can't be substituted by changing an HTTP header.
So the address 2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b can be abbreviated as 2001:db8:3c4d:15::1a2f:1a2b. You can use the two colon notation to replace any contiguous fields of all zeros in the IPv6 address.
If you use inet_pton()
first, and then convert it back to a string with inet_ntop()
you should have a consistent string representation. I wouldn't rely on the input to be consistent...
The CGI spec is clear that any RFC compliant IPv6 address is valid:
4.1.8. REMOTE_ADDR
The REMOTE_ADDR variable MUST be set to the network address of the
client sending the request to the server.
REMOTE_ADDR = hostnumber
hostnumber = ipv4-address | ipv6-address
ipv4-address = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit
ipv6-address = hexpart [ ":" ipv4-address ]
hexpart = hexseq | ( [ hexseq ] "::" [ hexseq ] )
hexseq = 1*4hex *( ":" 1*4hex )
The format of an IPv6 address is described in RFC 3513 [15].
A sane programmer validates all inputs. Therefore you should treat any environment variable as tainted input and validate/transform. Headers provided by a client, such as X-Forward-For et al should ALWAYS be treated with suspicion.
So what about expanding IPv6 addresses?
This question has been asked before and there are several solutions including a PEAR one
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With