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 SmithJul 26 '12 at 10:27

@Oleski Yes, I always use prepared statements, etc to validate user inputs, this was just my one exception. Thanks for the help.
–
Hope4YouJul 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.

"parameterization of queries rather than the use of prepared statements" performance?
–
curiousguyJul 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.
–
rookJul 25 '12 at 18:38

$_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.
–
LucJul 25 '12 at 19:52

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.