I do not seek to block users, nor do I block content, I would not care much if there was a false positive, because I am simply looking to integrate an additional step for those antecedents, adding a CAPTCHA to make life a bit difficult for spammers and malicious users.
So what I want to achieve is the following:
- If the user uses PROXY show the captcha
- If the user uses PROXY from the list of ports, show the captcha
- If the user’s IP is on the black list, show the captcha
I have already created my captcha image and, I retrieve the value / words as follows:
$_SESSION('code_captcha') = '';
$chars = array();
$imageWidth = 0;
$imageHeight = 0;
for ($i = 0; $i < $charsLength; $i++) {
//rest of the code of the captcha image...
If the user is between those conditions, I am going to show him a template where the captcha image will be displayed and the form where the text must be entered in the imput field to validate access to the page.
<input name="code_captcha" type="text">
The following code I have tested, I have used a VPN application and it has detected that I am using a PROXY:
if(!gethostbyaddr(getenv('REMOTE_ADDR'))
|| gethostbyaddr(getenv('REMOTE_ADDR')) == "."
|| !getenv('HTTP_ACCEPT_ENCODING')
|| getenv('HTTP_X_FORWARDED_FOR')
|| getenv('HTTP_X_FORWARDED')
|| getenv('HTTP_FORWARDED_FOR')
|| getenv('HTTP_VIA')
|| getenv('HTTP_FORWARDED')
|| getenv('HTTP_CLIENT_IP')
|| getenv('HTTP_FORWARDED_FOR_IP')
|| getenv('VIA')
|| getenv('X-PROXY-ID')
|| getenv('MT-PROXY-ID')
|| getenv('X-TINYPROXY')
|| getenv('PROXY-AGENT')
|| getenv('X_FORWARDED_FOR')
|| getenv('FORWARDED_FOR')
|| getenv('X_FORWARDED FORWARDED')
|| getenv('HTTP_X_CLUSTER_CLIENT_IP')
|| getenv('CLIENT-IP')
|| getenv('CLIENT_IP')
|| getenv('FORWARDED_FOR_IP')
|| getenv('HTTP_PROXY_CONNECTION')
|| getenv('PROXY_CONNECTION')
|| in_array(getenv('REMOTE_PORT'), array(8080,80,6588,8000,3128,553,554))
|| @fsockopen(getenv('REMOTE_ADDR'), 80, $NUM_ERROR, $CONNECTION_TIME, 0)
|| !getenv('HTTP_CONNECTION')){
echo 'proxy';
} else {
echo 'no proxy';
}
But in the event that it fails, I don’t know, if the most appropriate thing is to integrate a second check, adding the most common ports used by those VPN applications:
$PORT = $_SERVER('SERVER_PORT');
$PROXY_PORT = array("80","81","553","554","1080","3128","4480","6588","8000","8080");
//var_export ($PROXY_PORT);
//array_key_exists / in_array / array_search
if ((in_array($PORT, $PROXY_PORT) !== FALSE) && ($PROXY_PORT)) {
echo "Proxy";
} else {
echo "No proxy";
}
Finally, on the web and, in some directories, I have found some blacklists of IP addresses, the same ones that I have saved in a .txt file, I don’t know if it is the most appropriate or to store them in a MYSQL database:
$FILE_PATH = 'blocked_ips.txt';
function IP_ADDRESS() {
$IP_ADDRESS = '';
if (getenv('HTTP_CLIENT_IP'))
$IP_ADDRESS = getenv('HTTP_CLIENT_IP');
else if(getenv('HTTP_CF_CONNECTING_IP'))
$IP_ADDRESS = getenv('HTTP_CF_CONNECTING_IP');
else if(getenv('HTTP_X_REAL_IP'))
$IP_ADDRESS = getenv('HTTP_X_REAL_IP');
else if(getenv('HTTP_X_CLUSTER_CLIENT_IP'))
$IP_ADDRESS = getenv('HTTP_X_CLUSTER_CLIENT_IP');
else if(getenv('HTTP_X_FORWARDED_FOR'))
$IP_ADDRESS = getenv('HTTP_X_FORWARDED_FOR');
else if(getenv('HTTP_X_FORWARDED'))
$IP_ADDRESS = getenv('HTTP_X_FORWARDED');
else if(getenv('HTTP_FORWARDED_FOR'))
$IP_ADDRESS = getenv('HTTP_FORWARDED_FOR');
else if(getenv('HTTP_FORWARDED'))
$IP_ADDRESS = getenv('HTTP_FORWARDED');
else if(getenv('REMOTE_ADDR'))
$IP_ADDRESS = getenv('REMOTE_ADDR');
else
$IP_ADDRESS = 'UNKNOWN';
return $IP_ADDRESS;
}
$BLACK_LIST = file($FILE_PATH);
foreach (array_values($BLACK_LIST) AS $IP_BLOCKED){
if (trim($IP_BLOCKED) == IP_ADDRESS()){
//hide the web application, instead of the web page, show a template where the captcha image
//is located that the user must validate to access the page.
//Once this test is passed, the user will be able to access the web application.
include 'template_captcha.php';
exit;
}
}
echo 'Authorized!';
//access the web application
My captcha template: https://i.imgur.com/9ca3aVG.png
Now my question is this:
- How can I combine all my code, for verification, since the visiting user if he uses PROXY / VPN and, if he is in the black list, he will have to fill the CAPTCHA code?
But the user must be verified only once, because if the user passes the test, the validation of the Captcha code must be saved in a SESSION, to avoid that the Captcha code is shown again or appears when visiting another URL or when reloading the page, only in the event that the user closes the browser will they have to re-enter the CAPTCHA code.