Reputation: 31
this is my first post, hope to be posting the right content.
I designed this code, it blocks ips if the previous connection was made before a certain span of time and if this patron has been repeated x times (in the example code: if you have connected 10 times in less than 10 seconds in a row, in other words you are spending less than 10 seconds in each page you visit).
The questions:
Hope everything is clear. Thank you.
$ip = preg_replace('#[^0-9.]#', '', getenv('REMOTE_ADDR'));
$sql = db_query("SELECT * FROM `protect` WHERE `ip` LIKE '$ip' AND `blocked` LIKE 1 LIMIT 1");
$count = mysqli_num_rows($sql);
if($count != 0){
echo "Too many connections";
exit();
}
$sql = db_query("SELECT * FROM `protect` WHERE `ip` LIKE '$ip' LIMIT 1");
$count = mysqli_num_rows($sql);
if($count != 0){
while ($row = mysqli_fetch_array($sql, MYSQLI_ASSOC)){
$previousCon=$row["previousCon"];
$counter = $row["counter"];
}
$timeSpan=time()-strtotime($previousCon);
if($timeSpan>10){
$sql = db_query("UPDATE `protect` SET `counter`=0,`previousCon`=now() WHERE `ip` LIKE '$ip' LIMIT 1");
exit();
}else if($timeSpan<=10){
$counter++;
if($counter>=10){
$sql = db_query("UPDATE `protect` SET `blocked`= '1',`previousCon`=now() WHERE `ip` LIKE '$ip' LIMIT 1");
exit();
}else{
$sql = db_query("UPDATE `protect` SET `counter`='$counter',`previousCon`=now() WHERE `ip` LIKE '$ip' LIMIT 1");
exit();
}
}
}else{
$sql = db_query("INSERT INTO `protect` (`ip`,`previousCon`) VALUES ('$ip',now())");
exit();
}
Upvotes: 3
Views: 79
Reputation: 5030
Not only your code doesn't work as @rlanvin mentioned, your script will eventually bring down the site even no attacker attacks your site.
Your code search the whole table twice and for a certain percentage you need to search the third time to update a record. This is bad, really bad.
As your table record every unique IP that touches your server, your table will be growing very fast. Usually searching through a table with more than 100,000 records can cause serious harm to the performance (10+ seconds to respond), depending on how much computational power your server have. However, no matter how much computational power you have, as it is an ever growing table, it will eventually reach a point where it starts to harm your server's performance badly.
At first, it maybe just making your user wait, but when it reaches a certain time (usually 30 seconds), the server will take it as error and return exceeding time limit error. So your script will bring down your site even if there are no attacker at all.
Worst still, changing / faking IP is the basic of attacker. So when there is really an attacker, very likely he will be using a large amount of IP, which make your table grow to that breaking point real fast. So even if your firewall or other lower level structure (router, for example) block the attacker some time later, instead of returning to normal, the site is still down because of your script.
So, it is recommend that you don't use the script at all.
Upvotes: 0
Reputation: 6277
Is it worth the time and computing consumption just to check it?
Absolutely not.
The final objective is to prevent robots that might cause some damage to my website (some script that could damage my databases if I coded something wrong and didn't realise), but will the robots change ips each time they connect to somewhere so this code will do nothing?
There are different questions here.
Did you think of all the legitimate cases where many requests can come from the same IP address?
I was thinking about adding this code at the beginning of every raw php page, I mean the ones that just make changes in the server site... so maybe I can reduce the span and counter?
Seriously, don't do that.
You have one very specific use cases where throttling is useful: to prevent brute-forcing of passwords (typically in a login form). You don't do that by IP address only though (as we saw, it's mostly useless) but instead by user account. Too many failed attempt on one account? This account is locked for a few minutes.
Now if you have a specific IP address that is spamming your website, then banning it with a firewall or the web server directly is going to be much, much more efficient.
Upvotes: 4