1

Well, the question says it all, i am wondering, how secure is a comparison like:

if ($_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']) {
    // yeah, it's the server, go ahead do this.
}

The reason why i am asking is to identify some web api calls that are coming from the server itself.

I know that the $_SERVER['REMOTE_ADDR'] can be spoofed to run a request but not to get the result back from it. If this is the case, when talking about Rest for example, this rises no problem for GET requests for instance, but how about DELETE requests, where there is no need to parse the response from the server.
If the above statement is correct, means you should't trust the aftermentioned comparison?
What are the alternatives (let's exclude CLI from here) ?

Twisted1919
  • 2,430
  • 1
  • 19
  • 30
  • 3
    What about using some kind of password? – TimWolla Jun 22 '13 at 23:11
  • 1
    It is safe to assume that if `$_SERVER['REMOTE_ADDR']` is `127.0.0.1` or `$_SERVER['SERVER_ADDR']`, the request came from the server itself, but if you are not the only one running scripts in the server or the server is running a proxy service like Squid, you may be in trouble there. It should be proper to rely more in some authentication layer as TimWolla suggested. – Havenard Jun 22 '13 at 23:16
  • -- TimWolla yes you have a point there, checking against a password would also be smarter. -- Havenard - okay, but can't an attacker spoof it's ip to be 127.0.0.1 therefore it would trick the mechanism? – Twisted1919 Jun 22 '13 at 23:20
  • You cannot use a spoofed IP to stabilish a TCP session or any kind of two-way communication with any server. You don't have to worry about that here. – Havenard Jun 22 '13 at 23:21
  • @Havenard - okay, thanks for clearing that out :) – Twisted1919 Jun 22 '13 at 23:22
  • @TimWolla - if you care to change your comment into an answer so that i can accept it, it would be perfect :) – Twisted1919 Jun 22 '13 at 23:26
  • @Twisted1919 Done. I added some additional information as well :) – TimWolla Jun 22 '13 at 23:30

3 Answers3

1

This isn't a safe assumption. As @TimWolla has mentioned there are requests, for which $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'] would be true without the request originating at the server. Also consider other devices on a LAN. Consider this situation:

  • Your server has a local IP of 192.168.1.2
  • A malicious user on your network has a local IP of 192.168.1.3
  • Your network has a public IP of 1.2.3.4

If your server is listening to 1.2.3.4:80, a request form the malicious client to 1.2.3.4:80 would have $_SERVER['REMOTE_ADDR'] = '1.2.3.4'.

Because of this, if only your server needs to be able to access this functionality, you shouldn't publicly expose this port to the internet. You should configure a separate apache virtualhost on another port (say 81) and firewall that port so that it refuses all incoming connections that don't originate from the server itself.

Bailey Parker
  • 15,599
  • 5
  • 53
  • 91
  • 1
    Yeah, no. That's not how TCP works... The REMOTE_ADDR is the IP address of the client that needs to be handed the response. So if `REMOTE_ADDR` is `192.168.1.2` which is the same as the server, the request **came** from the server... This was considered when TCP and IP were designed... – ircmaxell Jun 22 '13 at 23:34
  • @ircmaxell Won't the `REMOTE_ADDR` and `SERVER_ADDR` be the same in my hypothetical situation even though the request came from another client on the LAN? – Bailey Parker Jun 22 '13 at 23:44
  • No. `REMOTE_ADDR` is **always** the reciever of the TCP packet. So if `REMOTE_ADDR` == `SERVER_ADDR`, either something is messed up in the server (which can happen), or your router has been compromised. Either way, it's not a common occurrence and not what you should depend (or not) upon... – ircmaxell Jun 23 '13 at 03:44
1

The best solution is using a secure password.

You won't have to worry about faked ip addresses or other possible insecure check that way, as long as your check only allows correct passwords.

if ($_GET['password'] === 'my_password') {
    // code
}

Consider using a secure compare function to avoid timing attacks.

Community
  • 1
  • 1
TimWolla
  • 31,849
  • 8
  • 63
  • 96
0

I'd say it is safe as long as it doesn't perform any harmful actions.

If someone spoofs the IP address then they won't receive the response since the server will send the response to itself and not the attacker.

So displaying a stack trace should be fine however, if you have some special action performed based on this, then the attacker could do damage without seeing the response.

Brad
  • 741
  • 7
  • 17