Cyclone
Cyclone

Reputation: 18295

IP address SQL injection

Is it possible for a user to forge the result that is returned from $_SERVER['REMOTE_ADDR'] in PHP so they could in theory use SQL injection on a database?

This is a bit dumb, but I'm still new enough to PHP that I want to know if it can be done, whether or not I need to sanitize database input when the SELECT statement chooses from IP addresses returned from $_SERVER['REMOTE_ADDR']. So, if I wanted to use something like $query = "SELECT * FROM users WHERE IP='" . $_SERVER['REMOTE_ADDR'] . "'";, would there be any danger to my doing this?

Again, probably a "nooby" question, but I feel it must be asked.

Thanks

Upvotes: 15

Views: 10753

Answers (8)

Neil N
Neil N

Reputation: 25278

It's a stretch, and unlikely, but I wouldn't go as far as to say it's impossible. So....

Use parameterized queries anyways.

Even if you never get attacked via the IP address field, you will still get the added benefit of faster queries through caching.

Upvotes: 17

Andrew McGregor
Andrew McGregor

Reputation: 34662

You can't rely on REMOTE_ADDR being true... it could be the wrong address due to anonymising proxies or some such trick. You can rely on it always being an IP address, so SQL injection by this path is impossible.

Way down at the bottom of the stack, that's been converted from the source address on the packets making the TCP connection to your server. That means a) it has to be an IP address and b) it has to route back to the client for the connection to happen at all.

Upvotes: 14

JAL
JAL

Reputation: 21563

For efficiency and safety you may wish to store and work with IPs as ints in your database.

The straightforward way to store IP addresses is to use a varchar field in your DB. However, another way to represent IPs is as an integer. Converting the supplied IP in this way will sanitize it, and also make your storage and queries more efficient. Storing an INT takes up less space in a DB, and works better for indexing and I believe query caching.

Check out ip2long and long2ip for PHP functions to convert, and inet_aton and inet_ntoa to do it in MySQL.

So, the process might go like

$user_ip=ip2long($_SERVER['REMOTE_ADDR']);
if(!$user_ip){ //returned false due to odd input
   echo 'wtf, yo';
   }
else{
   //do your query
   }

You can also sanitize an IP and keep it in the original dotted quad form by combining the two

$user_ip=long2ip(ip2long($_SERVER['REMOTE_ADDR']));

Upvotes: 1

Jimmie Lin
Jimmie Lin

Reputation: 2215

I always put this code in all my projects (some initial input sanitization), to prevent something nasty with faked IPs going on. I am not sure whether they can fake the REMOTE_ADDR anyway.

function validate_ip($ip) {
    // Try IPv4 First, as its the most used method right now
    if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
        // Oops... try v6
        if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            return false; // Sorry...
        }
        else {
            return true;
        }
    }
    else {
        return true;
    }
}
if(!isset($_SERVER['REMOTE_ADDR'])) # wtf?
    die("Could not find your IP Address...");
else {
    if(validate_ip($_SERVER["REMOTE_ADDR"]))
        die("Could not validate your IP Address...");
}

Upvotes: 1

outis
outis

Reputation: 77450

REMOTE_ADDR isn't sent by the client, it's set by the server. While it's technically possible to spoof an IP address at the network level, the attacker has to work blind. The trickiest part is guessing the sequence number. (Under Coldfusion, by the way, it's another story.)

As others have said, use prepared statements and you don't need to worry about SQL injection (though other types of injection attacks are possible).

Upvotes: 1

danben
danben

Reputation: 83310

I think the only way for someone to forge $_SERVER['REMOTE_ADDR'] would be to construct a IP packet with a fake IP address (because it is set by the server, not the client), in which case responses would be routed back to the faked address. If you're worried about injection attacks, I think you're ok because the address fields in IP packets only have room for addresses.

Upvotes: 7

simeonwillbanks
simeonwillbanks

Reputation: 1459

You could use PHP's Data Filtering Functions.

filter_var() with FILTER_VALIDATE_IP will validate the remote IP. If the remote IP is valid, use it in SQL.

EDIT: filter_input() with INPUT_SERVER is another option ;)

http://www.php.net/manual/en/book.filter.php

http://www.php.net/manual/en/filter.filters.validate.php

http://www.php.net/manual/en/function.filter-var.php

http://www.php.net/manual/en/function.filter-input.php

Hope this helps,

Simeon

Upvotes: 2

K Prime
K Prime

Reputation: 5849

Always sanitize all external inputs - use mysql_real_escape_string, or better still, prepared statements

Upvotes: 6

Related Questions