Get client’s real IP address on Heroku

From Jacob, Heroku’s Director of Security at the time:

The router doesn’t overwrite X-Forwarded-For, but it does guarantee that the real origin will always be the last item in the list.

This means that, if you access a Heroku app in the normal way, you will just see your IP address in the X-Forwarded-For header:

$ curl http://httpbin.org/ip
{
  "origin": "123.124.125.126",
}

If you try to spoof the IP, your alleged origin is reflected, but – critically – so is your real IP. Obviously, this is all we need, so there’s a clear and secure solution for getting the client’s IP address on Heroku:

$ curl -H"X-Forwarded-For: 8.8.8.8" http://httpbin.org/ip
{
  "origin": "8.8.8.8, 123.124.125.126"
}

This is just the opposite of what is described on Wikipedia, by the way.

PHP implementation:

function getIpAddress() {
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ipAddresses = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        return trim(end($ipAddresses));
    }
    else {
        return $_SERVER['REMOTE_ADDR'];
    }
}

Leave a Comment