Find the IP address of your website’s visitors

ipapi ~ ipapi.co
5 min readSep 10, 2019

--

client IP address

Fetching the IP address of a website visitor is a common requirement for web developers. It can serve multiple purposes like logging, tracking user behavior, or even security. However, blindly relying on some common methods to obtain the IP address can leave you open to security risks.

There are dozens of posts on Q & A sites & forums that essentially ask : “How can I find the IP address of my website’s visitor”. The questions have collectively gathered thousands of votes and millions of views.

TL;DR : There are several ways to find the IP address of your client but the answer depends on your setup. Some methods are prone to spoofing. 

A very common theme in the answers is trial and error like the if-else block below. Please don’t copy it without understanding what it is doing as it can open your code to dangerous attacks.

Warning ! Do NOT copy this blindly

The problem with these methods is :

  • HTTP headers can be easily spoofed: Malicious users can send fake headers.
  • Backend Configurations: Reverse proxies, load balancers, or CDN services might alter the headers.

Let’s look at some examples in PHP to understand this. $_SERVER is an array of headers created by the web server. Some of the variables that can help us find the IP address of the client are :

REMOTE_ADDR
HTTP_CLIENT_IP
HTTP_COMING_FROM
HTTP_FORWARDED
HTTP_FORWARDED_FOR
HTTP_FROM
HTTP_PROXY_CONNECTION
HTTP_VIA
HTTP_X_COMING_FROM
HTTP_X_FORWARDED
HTTP_X_FORWARDED_FOR
HTTP_X_REAL_IP

The most commonly used headers for finding the IP address of a client in PHP are :

  1. REMOTE_ADDR — This is the IP address from which the request is received by the web server. Depending on your configuration, this may not always be the IP address of your client (e.g. it may be the IP of the proxy sitting just before the web server that intercepts the requests). Here are a few examples:
    - $_SERVER[“REMOTE_ADDR”] gives server IP rather than visitor IP
    - $_SERVER[‘REMOTE_ADDR’] not giving the right ip address
  2. HTTP_CLIENT_IP: This header is generally set by the client or a proxy.
  3. HTTP_COMING_FROM: Rarely used, but it would contain the IP address of the incoming request.
  4. HTTP_FORWARDED: This header contains a possibly comma-separated list of IPs that have forwarded the request.
  5. HTTP_FORWARDED_FOR: Similar to HTTP_FORWARDED but more commonly used. Often contains a list of IPs.
  6. HTTP_FROM: Contains the email address of the user making the request, not an IP address.
  7. HTTP_PROXY_CONNECTION: Irrelevant for IP addresses, it indicates that the client is connecting via a proxy.
  8. HTTP_VIA: Indicates intermediate proxies through which the request has passed.
  9. HTTP_X_COMING_FROM: Similar to HTTP_COMING_FROM, but less standard.
  10. HTTP_X_FORWARDED: Usually set by proxy servers, contains the original IP.
  11. HTTP_X_FORWARDED_FOR: A more standardized version of HTTP_X_FORWARDED, set by proxy servers. This is a list of IP addresses starting from the original client and including each successive proxy that intercepted the request. Theoretically you can obtain the client’s IP address from this list. Unfortunately, this header can be easily spoofed.
  12. HTTP_X_REAL_IP: This header is generally set by a reverse proxy to indicate the real IP address of the original client.

Examples :

We’ll look at three commonly use headers: REMOTE_ADDR, HTTP_X_REAL_IP, and HTTP_X_FORWARDED_FOR, and explain when to use each.

PHP

  1. REMOTE_ADDR: This is the most reliable method to get a client’s IP address when your application is not behind a proxy. Use $_SERVER['REMOTE_ADDR'] in this case.
  2. HTTP_X_REAL_IP: Use this when your PHP application is behind a reverse proxy like NGINX or Apache. It’s safer to use $_SERVER['HTTP_X_REAL_IP'] when available, but fall back to $_SERVER['REMOTE_ADDR'] if it's not.
  3. HTTP_X_FORWARDED_FOR: If your application is behind a proxy that forwards this header, then you can use $_SERVER['HTTP_X_FORWARDED_FOR']. This can sometimes contain a list of IPs; the first one is usually the original client IP.

Python (Flask)

  1. REMOTE_ADDR: Use request.remote_addr when your application isn't behind a proxy.
  2. HTTP_X_REAL_IP: When behind a proxy, you can use request.headers.get('X-Real-IP', request.remote_addr) to get the client's real IP address.
  3. HTTP_X_FORWARDED_FOR: You can use request.headers.get('X-Forwarded-For', request.remote_addr).split(',')[0].strip() if you're behind a proxy that includes this header.

Java

  1. REMOTE_ADDR: In a Java servlet, request.getRemoteAddr() gives you the IP address when not behind a proxy.
  2. HTTP_X_REAL_IP: When behind a proxy, use request.getHeader("X-Real-IP"). Fall back to request.getRemoteAddr() if this header is not available.
  3. HTTP_X_FORWARDED_FOR: Similar to above, use request.getHeader("X-Forwarded-For") when you know the proxy forwards this header.

Ruby (Rails)

  1. REMOTE_ADDR: In Ruby on Rails, use request.remote_ip to get the client's IP if not behind a proxy.
  2. HTTP_X_REAL_IP: When behind a proxy, request.env["HTTP_X_REAL_IP"] can be more reliable.
  3. HTTP_X_FORWARDED_FOR: If the proxy forwards this header, request.env['HTTP_X_FORWARDED_FOR'] can be used.

Go

  1. REMOTE_ADDR: Use net.SplitHostPort(r.RemoteAddr) for the client's IP when not behind a proxy.
  2. HTTP_X_REAL_IP: When behind a proxy, try r.Header.Get("X-Real-IP"). If empty, use net.SplitHostPort(r.RemoteAddr) as a fallback.
  3. HTTP_X_FORWARDED_FOR: If the proxy sets this header, use r.Header.Get("X-Forwarded-For").

C#

  1. REMOTE_ADDR: Use HttpContext.Current.Request.UserHostAddress when not behind a proxy (or HttpContext.Connection.RemoteIpAddress for ASP.NET Core).
  2. HTTP_X_REAL_IP: When behind a proxy, use HttpContext.Current.Request.Headers["X-Real-IP"]. If it's null, fall back to the remote address (or HttpContext.Request.Headers["X-Real-IP"] for ASP.NET Core).
  3. HTTP_X_FORWARDED_FOR: When your application is behind a proxy that sets this header, you can use HttpContext.Current.Request.Headers["X-Forwarded-For"](or HttpContext.Request.Headers["X-Forwarded-For"] for ASP.NET Core).

Key points to keep in mind

  • Do not blindly trust any data sent from the client
  • Avoid copy pasting code samples because the solutions are often specific to a particular backend configuration.
  • Some of the solutions might appear to work in your development environment but you should make sure that you aren’t opening a security hole (e.g. Anatomy of an Attack: How I Hacked StackOverflow)

On a side note, if the IP address is only needed on your client side, you can find it by sending a request to ipapi.co/ip from your client. The value returned is the IP address in text format. Both IPv4 and IPv6 clients are supported.

--

--

ipapi ~ ipapi.co

IP Lookup | IP Geolocation API | IP Address Locator by Kloudend, Inc. USA. Trusted by Fortune 500 !