Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

In PHP I retrieve a user's IP address ($_SERVER['REMOTE_ADDR']) to use it in some MySQL queries, but I do not validate them to be true IP addresses.

Should I validate user IP addresses before using them in MySQL queries, or will they always be valid IP addresses when I use $_SERVER['REMOTE_ADDR']? I'm trying to prevent an SQL injection.

If I should validate, which PHP function do you recommend to use? Should I send the IP address through mysqli_real_escape_string(), etc?

share|improve this question
    
There are cases when this variable is passed not from Apache but some rough script and eventually can be overwritten by adding other headers which value is not validated, like forwarded-for, so you have to actually parse it that it's valid ip address. –  Andrew Smith Jul 26 '12 at 10:27

3 Answers 3

up vote 13 down vote accepted

You should use prepared statements to prevent SQL injections. Take a look at this question.

However, $_SERVER['REMOTE_ADDR'] should be a valid IP address as it comes from the server, as verified by the TCP handshake. See this question for an extended discussion on this.

share|improve this answer
3  
Only variables prefixed with HTTP_ are pulled from the HTTP header (hence the prefix): stackoverflow.com/questions/6474783/… –  msanford Jul 25 '12 at 16:00
1  
@msanford My mistake. I've updated my answer accordingly. –  Oleksi Jul 25 '12 at 16:30
1  
+1 Good answer. –  msanford Jul 25 '12 at 16:31
    
@Oleski Yes, I always use prepared statements, etc to validate user inputs, this was just my one exception. Thanks for the help. –  Hope4You Jul 25 '12 at 19:02
3  
As a general note, I do not recommend saying something is "safe". That's too broad. You have to ask: "safe for what purpose?". To pick a silly example: I may trust my sister with my kids but not my car keys, and trust my neighbor with my car keys but not my kids. Get yourself into the habit of, whenever you say "safe", articulating what purpose it is safe for -- that will help you steer clear of security problems. –  D.W. Jul 25 '12 at 19:23

From this page it looks like the REMOTE_ADDR element of the $_SERVER array is populated by the server as opposed to being passed by the client, so it should (absent any bugs) be a reasonable assumption that it is the IP address of the remote client (or a proxy server acting on behalf of the remote client).

As @Lucb1e commented below some elements of the $_SERVER array come from the client and should be less trusted

As @Oleksi mentions not trusting input to SQL queries is a good idea in general.

share|improve this answer
    
"parameterization of queries rather than the use of prepared statements" performance? –  curiousguy Jul 25 '12 at 18:24
1  
+1 I agree. Also I have verified that at least with PHP+Apache this variable comes from Apache's socket and cannot be influenced. Also CSRF is still a problem with an ip address check. –  Rook Jul 25 '12 at 18:38
    
Thanks Rory and Rook –  Hope4You Jul 25 '12 at 19:01
    
$_SERVER also contains data inputted by the user: all HTTP headers, the query_string, and perhaps others. You shouldn't trust $_SERVER["HTTP_REFERER"] for example. The remote address should be fine though, as said by others. –  Luc Jul 25 '12 at 19:52
1  
@Lucb1e ta, updated to reflect that –  Rоry McCune Jul 25 '12 at 20:07

REMOTE_ADDR is determined by the receiving TCP stack - it's not data 'sent' by the client. Neither IPv4 nor ipv6 use characters which are unsafe / delimit expressions in SQL.

However there's very little point in storing the IP address (i.e. xxx.xxx.xxx.xxx or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx) the numeric value is far more useful and requires less storage - see the manual for the inet_aton() and inet6_aton() functions.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.