Block Proxy Visits with PHP

[ Block Proxy Visits with PHP ] I wrote recently about how to block proxy visits with WordPress. That article provides a simple, plug-&-play script that you can drop into WordPress-powered site. This article goes further with two effective techniques for blocking proxy visits to your site using only PHP. These techniques work for any PHP-enabled site, including WordPress, Drupal, Joomla, and many others. And they’re both easy to implement. Just a few minutes and your site can be relatively free of most proxy visits.

Why block proxies?

Proxy services are used for all sorts of malicious activity. Anything that bad actors want to accomplish, if they are savvy they’re going to use some sort of a proxy to help obscure their true identity. Proxies are used for things like spamming, scraping content, cheating authentication, obscuring identity, and scanning for exploits. In general, most malicious activity is associated with some sort of proxy service. With that in mind, here are some good reasons why you would want to block proxies from accessing your website:

  • Save valuable server resources like bandwidth and memory
  • Ensure accurate user identification (i.e., registration, voting, et al)
  • Secure your site against a wide range of malicious activity

So those are the main benefits, but there also is a big downside to consider. Decent folk (and software) use proxies for good instead of evil. For example, troubleshooting site connectivity issues is greatly facilitated when you can use a proxy service to access the site. And there are many other good ways to use a proxy; in many cases, the user simply wishes to remain anonymous, so they aren’t tracked, ad-targeted, and so forth. Additionally, many ISPs send customer traffic through a proxy server. So with that in mind, here are the reasons why you would NOT want to block proxies:

  • May end up blocking some legit proxy users
  • Slight performance hit required for certain proxy-blocking techniques

So basically it all boils down to how many of your legit visitors (including apps, etc.) are using a proxy to access your site. If minimal, then the potential benefits may outweigh the downsides. Totally your call, just want you to be aware of both sides of the equation. It’s also possible to take the middle ground and block proxies conditionally, by evaluating other aspects of each HTTP request and acting accordingly.

Can’t block them all

Here is something else to consider when deciding whether or not to block proxy servers. It’s impossible to accurately block all proxies with a simple code snippet. Proxy technology continues to evolve quickly in terms of functionality, complexity, and effectiveness. So there’s not really a one-size-fits-all, plug-&-play way to block 100% all proxies. That said, the techniques covered in this article provide simple, cost-effective, easy-to-implement solutions for blocking a wide range of proxy services (but not all of them).

Block proxy visits via HTTP headers

Most transparent proxies identify their functionality by sending a proxy header along with each HTTP request. This means that we can block a wide range of proxy visits by checking HTTP headers and denying access to anything that claims to be a proxy. Here is how we can achieve this using a simple PHP function:

function shapeSpace_block_proxy_visits() {
	
	$headers = array('CLIENT_IP','FORWARDED','FORWARDED_FOR','FORWARDED_FOR_IP','VIA','X_FORWARDED','X_FORWARDED_FOR','HTTP_CLIENT_IP','HTTP_FORWARDED','HTTP_FORWARDED_FOR','HTTP_FORWARDED_FOR_IP','HTTP_PROXY_CONNECTION','HTTP_VIA','HTTP_X_FORWARDED','HTTP_X_FORWARDED_FOR');
	
	foreach ($headers as $header){
		if (isset($_SERVER[$header])) {
			die('Proxy access not allowed.');
		}
	}
}

This function begins by defining a list of known proxy headers. It then loops through the list to check if any of the headers were sent with the request. If so, then the request is denied via die() and a simple message.

The downside to this technique is that not all proxies send headers that identify themselves as such. So while this is one of the better solutions performance-wise, it’s not as effective as the next technique, which is much better at blocking the more anonymous proxy services.

Block proxy visits via port scanning

This second proxy-block technique works by scanning for commonly used ports on the remote machine. If one of the ports is found open, most likely the request is routed via proxy server. Here is an example of this strategy, implemented via simple PHP function.

function shapeSpace_block_proxy_visits() {
	
	$ports = array(80,81,553,554,1080,3128,4480,6588,8000,8080);

	foreach ($ports as $port) {
		if (@fsockopen($_SERVER['REMOTE_ADDR'], $port, $errno, $errstr, 5)) {
			die('Proxy access not allowed.');
		}
	}
}

Because it doesn’t rely on the proxy header information, this solution is more effective than the previous technique. The downside here is that scanning for open ports requires more time than simply checking for HTTP headers. So keep an eye on your site’s performance if implementing this code. FYI, this is an improved version of the technique provided in my tutorial, Block Tough Proxies.

Note regarding scanning: best practice dictates that you only scan each IP address only one time. To accomplish this, you could adapt the previous script to store scan results for each IP address in the database, and then check for existing IPs before doing each scan. This strategy helps keep visitors happy and also optimizes for performance.

Going further

If you’re getting into crafting solutions for blocking proxy visits, here are some useful resources for going further:

Also, if your site supports .htaccess, you can get better performance by blocking proxies at the server level. Here are a couple of tutorials with more information: