I have a site where a user submits a message using AJAX to a file called like.php
. In this file the users message is submitted to a database and it then sends a link back to the user. In my Javascript code I disabled the text box the user types into when they submit the AJAX request.
The only problem is, a malicious user can just constantly send POST requests to like.php
and flood my database. So I would like to implement simple flood protection.
I don't really want the hassle of another database table logging users IPs and such... as if they are flooding my site there will be a lot of database read/writes slowing it down. I thought about using sessions, like have a session that contains a timestamp that gets checked every time they send data to like.php
, and if the current time is before the timestamp let them add data to the database, otherwise send out an error and block them. If they are allowed to enter something into the database, update their session with a new timestamp.
What do you think? Would this be the best way to go about it or are there easier alternatives?
Thanks for any help. :)
HydraBarrier is an effective alternative to sand bags when it comes to spill containment and similar water containment and prevention applications. These water barriers are durable, come in a variety of sizes, are reusable, and can be filled when needed and emptied once used. This makes storing them a simple task.
Using Sand Bags. Traditional sand bags are an effective way to deflect water and help protect structures from flooding. Sand bags can be made of burlap, polypropylene, polyethylene and nylon.
What are temporary flood barriers? Temporary flood barriers consist of portable metal frames with a waterproof cover, designed to be quickly set up in pre-planned locations which do not have permanent defences. When flooding is expected, the barriers are quickly put up.
Well I made a script to handle it for core requests only (no session requests or other requests who aren't calling the core). If you have a look to google you'll find scripts/classes which will kill your server because of high loads every time. The fact, that many use SESSIONs and maybe ALSO SQL/Database will let you get a flooding protection as a server-killer. Also the fact that SESSIONs need a Cookie (or a GET SID) so you can manipulate SESSIONs easy to get a new SESSION ID.
My function is text-based and do a simple handling. The bad thing is that you maybe have to use a CronJob to delete ips from time to time. Comparing to other scripts its about 10* faster (and more save than sessions).
I don't know if its really useful at all. ;) You maybe like to change the rpm value to less or/and also the 200 req. My setting is a ban for a bot doing interval requests in <=6 seconds.
<?php
function ht_request_limiter() {
if (!isset($_SERVER['REMOTE_ADDR'])) { return; } // Maybe its impossible, however we check it first
if (empty($_SERVER['REMOTE_ADDR'])) { return; } // Maybe its impossible, however we check it first
$path = '/your/path/ipsec/'; // I use a function to validate a path first and return if false...
$path = $path.$_SERVER['REMOTE_ADDR'].'.txt'; // Real file path (filename = <ip>.txt)
$now = time(); // Current timestamp
if (!file_exists($path)) { // If first request or new request after 1 hour / 24 hour ban, new file with <timestamp>|<counter>
if ($handle = fopen($path, 'w+')) {
if (fwrite($handle, $now.'|0')) { chmod($path, 0700); } // Chmod to prevent access via web
fclose($handle);
}
}
else if (($content = file_get_contents($path)) !== false) { // Load existing file
$content = explode('|',$content); // Create paraset [0] -> timestamp [1] -> counter
$diff = (int)$now-(int)$content[0]; // Time difference in seconds from first request to now
if ($content[1] == 'ban') { // If [1] = ban we check if it was less than 24 hours and die if so
if ($diff>86400) { unlink($path); } // 24 hours in seconds.. if more delete ip file
else {
header("HTTP/1.1 503 Service Unavailable");
exit("Your IP is banned for 24 hours, because of too many requests.");
}
}
else if ($diff>3600) { unlink($path); } // If first request was more than 1 hour, new ip file
else {
$current = ((int)$content[1])+1; // Counter + 1
if ($current>200) { // We check rpm (request per minute) after 200 request to get a good ~value
$rpm = ($current/($diff/60));
if ($rpm>10) { // If there was more than 10 rpm -> ban (if you have a request all 5 secs. you will be banned after ~17 minutes)
if ($handle = fopen($path, 'w+')) {
fwrite($handle, $content[0].'|ban');
fclose($handle);
// Maybe you like to log the ip once -> die after next request
}
return;
}
}
if ($handle = fopen($path, 'w+')) { // else write counter
fwrite($handle, $content[0].'|'.$current .'');
fclose($handle);
}
}
}
}
Edit: My way to test the request time was with microtime and simulate 10'000 users. I ask google and tested (as example) http://technitip.net/simple-php-flood-protection-class
So I don't know what should be simple there? You have about 3 SQL Requests at one time like:
$this -> user_in_db($ip))
$this->user_flooding($ip);
$this->remove_old_users();
It maybe supply more functions, but all legit users use servertime for nothing. ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With