Detect clients with Proxy Servers via PHP-ThrowExceptions

Exception or error:

I’m looking for a method, or a way to detect clients using any type of proxy server viewing my web site. I’m using PHP/Apache… what’s the best way to do this? Any proxy server would need to be detected, not specifically one or the other.


I am more interested in the anonymous proxies… as the normal ones are easily detected by looking for HTTP_X_FORWARDED_FOR.

Another Edit

Try this:

1) go to (or any other free anonymous proxy site)

2) visit:

3) they are able to block somehow, as the page errors out with “Error loading stylesheet: A network error occurred loading an XSLT stylesheet:

I want to do something similar to prevent proxies.

How to solve:

You can’t detect that unless they pass on special headers which explictly mention it like X-Forwarded-For or something.

As far as I know you have to use a blacklist. Users who use putty portforwarding, VPN or other more sophisticated methods are undetactable as they behave exactly like normal users.


Use the following 2 solutions in PHP.
// method 1 = quick but does not work with anonymous proxies

    $proxy_headers = array(
    foreach($proxy_headers as $x){
        if (isset($_SERVER[$x])) die("You are using a proxy!");

// Method 2 = portscan back to the origin IP at the normal proxy ports used.

    $ports = array(8080,80,81,1080,6588,8000,3128,553,554,4480);
    foreach($ports as $port) {
         if (@fsockopen($_SERVER['REMOTE_ADDR'], $port, $errno, $errstr, 30)) {
              die("You are using a proxy!");


Metasploit uses lots of different techniques to force client’s system to make direct connection (vulnerabilities/misfeatures in Flash, Java, QuickTime, MS Office, custom DNS server).

Alternatively, if you can’t get client’s browser to launch metasploit, you could try to look for open proxies (port scanning) and known Tor exit nodes.

But please don’t assume that proxies are evil and need to be blocked – there are plenty of legitimate proxies and some users have to use them.

If you have trouble with spam or other abusive traffic then just blocking of proxies won’t help much. You should look for specific solutions that address core of the problem (spam filters, IDS) rather than assuming anonymous = guilty.


There are various paid / free solutions. Most of them looks at the client IP trying to connect to determine if they’re on a proxy or not.

Maxmind – They focus on fraud detection and have a sub-category for proxy detection. Note that this is now considered as a “legacy” service.

W I T C H – Able to detect OpenVPN by looking at MSS values that are uniquely identifiable. The code is available on github.

GetIpIntel – Proxy / VPN detection using machine learning, queries via API.

There are a few more free options listed on security stack exchange.


Everything that the client passes to the server can be self-configured. You cannot trust anything, except for an IP address. So you cannot check the header data, if it’s a proxy or a normal client.
By the way: It’s the intention of a proxy not to show being a proxy 🙂

For sure, you could take the requester’s IP address and send a http request you would send to a proxy. If it reacts, it may be a proxy otherwise, it’s a normal client. This method would be very expensive and not reliable. If the proxy your server requested was behind a firewall, you would get no answer and think that it is a normal client.


I think that what’s happening here is some client-side JavaScript is trying to load something, and that can “see” that the page is being viewed inside a frame. That might be a more fruitful avenue to explore- as other answers have indicated, proxies intentionally make it hard to determine just from the server alone.


Old topic, but I might have figured something out.

It is live on my site and I think it might work for most cases.

My problem was that banned user were coming back to my site and re-registering with a new email address using one of the many proxies that you can find. What I have done is a simple jQuery call on the registration/login form:

<form id="login_form" method="post" action="/#fake_login_url">
   stuff you need for the form


Even if it’s an old question, I’ve had to check for proxy and unfortunatly none of the answers give good result.

After searching, I’ve found a better method. In order to understand this way of doing, just create a small page with this code:

 foreach ($_SERVER as $key => $val)
     echo $key."<br>\n";  

Run it direclty from your server. You’ll see all keys from the header your server is sending. Then run the same script through a Proxy.
You’ll see (depending on the Proxy) 3 possible results:

  1. the Proxy add news keys/values
  2. the Proxy don’t send all the original keys/values so some are missing.
  3. the Proxy send exactly the same keys/values but not in same order
  4. the Proxy send exactly the same keys/values, in same order

The 4th case can happen but others are the most frequent.
So you just have to create an array with the key/value from your server (based on the result when you run the script without a Proxy) and compare the keys/values from $_SERVER. If you don’t have exacty the same keys/values (less, more or in other order) you can assume the page came from a Proxy.

Notice I agree with those saying in some cases Proxy can be use in a “legal”.


i feel like answering an 8 year old thread is useless, but i will answer anyways for future reference.
I dont know about proxies, but most VPN’s (if you go to them) will bring some sort of error page. if you did something like…

$cont = file_get_contents($_SERVER["REMOTE_ADDR"]); //the users ip
$errormsg = "nginx";
if(strpos($cont, $errormsg)){
    die("No VPN's or Proxies Allowed");

this is very basic, you could get an array of the error messages and do it that way.
This will not work if the user has portforwarded their 80 port, but i dont see why the common person would do this.


I’m using the following, but I’m not sure if it is working every time.
It’s just an idea 🙂

$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
if ($host != $_SERVER['REMOTE_ADDR']) die('Proxy detected.');

Leave a Reply

Your email address will not be published. Required fields are marked *