Re: $_SERVER['REMOTE_ADDR'] and sql injection
| From: | Andrew Ballard | Date: | Wed, 23 Jun 2010 15:57:05 +0000 |
| Subject: | Re: $_SERVER['REMOTE_ADDR'] and sql injection | ||
| References: | 1 2 3 4 5 6 7 8 9 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-306380@lists.php.net to get a copy of this message | ||
On Wed, Jun 23, 2010 at 11:09 AM, Ashley Sheridan
<ash@ashleysheridan.co.uk> wrote:
> Out of interest, how does PHP calculate the IP number, as it was my understanding of IP numbers
> that they can't be negative.
>
> For example, my IP address is 89.243.156.135
> The four parts as binary:
> 01011001
> 11110011
> 10011100
> 10000111
>
> From there, I thought that the binary values were concatenated as if they were a string, and
> then the decimal value worked out from that, giving, in my case, a value of 1509137543.
>
> How is it possible that PHP can produce negative values from this method? Does it do something
> else entirely, or is this a case of the integer value overflowing into negative values? (which might
> explain why the value correctly converts back)
>
> If so, what would be the best method to get the correct value, as abs() obviously isn't
> it!
>
> Thanks,
> Ash
> http://www.ashleysheridan.co.uk
>
>
It has to do with the storage of the value as a 4-byte integer, as Bob
mentioned. The best way I know of in PHP involves either sprintf
dechex, or pack/unpack. If you use pack/unpack, just be careful with
the endian-ness of the format you choose:
<?php
$x = ip2long('192.168.0.1');
var_dump($x);
// int(-1062731775)
var_dump(long2ip($x));
// string(11) "192.168.0.1"
var_dump(long2ip(abs($x)));
//string(13) "63.87.255.255"
var_dump(sprintf('%u', $x));
// string(10) "3232235521"
var_dump((float) sprintf('%u', $x));
// float(3232235521)
var_dump(pack('L', $x));
// binary value, machine-dependent byte order
var_dump(pack('N', $x));
// binary value, big-endian
var_dump(pack('V', $x));
// binary value, little-endian
var_dump(dechex($x));
// string(8) "c0a80001"
?>
I'm not sure how any of these are best passed along to various
databases, though. I believe something like this should work, as long
as the column defined with a type that will hold the positive value,
such as BIGINT (or, perhaps INT(10) UNSIGNED in MySQL, though I think
I remember having issues with that type).
$sql = sprintf('INSERT INTO
mytable (ip_address) VALUES (%u)',
ip2long($ip));
I do most of my development with SQL Server, so I often just pass the
value as a 4-byte integer (or sometimes even in dotted notation) to a
stored procedure and then let T-SQL do the work.
Andrew