Prevent PHP script from being flooded

妖精的绣舞 提交于 2019-11-27 08:48:00

You can use memcache to do this ..

Simple Demo Script

$memcache = new Memcache ();
$memcache->connect ( 'localhost', 11211 );
$runtime = $memcache->get ( 'floodControl' );

if ((time () - $runtime) < 2) {
    die ( "Die! Die! Die!" );
} 

else {
    echo "Welcome";
    $memcache->set ( "floodControl", time () );
}

This is just a sample code .. there are also other thing to consider such as

A. Better IP address detection (Proxy , Tor )

B. Current Action

C. Maximum execution per min etc ...

D. Ban User after max flood etc

EDIT 1 - Improved Version

Usage

$flood = new FloodDetection();
$flood->check();

echo "Welcome" ;

Class

class FloodDetection {
    const HOST = "localhost";
    const PORT = 11211;
    private $memcache;
    private $ipAddress;

    private $timeLimitUser = array (
            "DEFAULT" => 2,
            "CHAT" => 3,
            "LOGIN" => 4 
    );
    private $timeLimitProcess = array (
            "DEFAULT" => 0.1,
            "CHAT" => 1.5,
            "LOGIN" => 0.1 
    );

    function __construct() {
        $this->memcache = new Memcache ();
        $this->memcache->connect ( self::HOST, self::PORT );
    }

    function addUserlimit($key, $time) {
        $this->timeLimitUser [$key] = $time;
    }

    function addProcesslimit($key, $time) {
        $this->timeLimitProcess [$key] = $time;
    }

    public function quickIP() {
        return (empty ( $_SERVER ['HTTP_CLIENT_IP'] ) ? (empty ( $_SERVER ['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER ['REMOTE_ADDR'] : $_SERVER ['HTTP_X_FORWARDED_FOR']) : $_SERVER ['HTTP_CLIENT_IP']);
    }

    public function check($action = "DEFAULT") {
        $ip = $this->quickIP ();
        $ipKey = "flood" . $action . sha1 ( $ip );

        $runtime = $this->memcache->get ( 'floodControl' );
        $iptime = $this->memcache->get ( $ipKey );

        $limitUser = isset ( $this->timeLimitUser [$action] ) ? $this->timeLimitUser [$action] : $this->timeLimitUser ['DEFAULT'];
        $limitProcess = isset ( $this->timeLimitProcess [$action] ) ? $this->timeLimitProcess [$action] : $this->timeLimitProcess ['DEFAULT'];

        if ((microtime ( true ) - $iptime) < $limitUser) {
            print ("Die! Die! Die! $ip") ;
            exit ();
        }

        // Limit All request
        if ((microtime ( true ) - $runtime) < $limitProcess) {
            print ("All of you Die! Die! Die! $ip") ;
            exit ();
        }

        $this->memcache->set ( "floodControl", microtime ( true ) );
        $this->memcache->set ( $ipKey, microtime ( true ) );
    }

}
  1. Store the last execution time of your script in a database or a file.
  2. Read from that file/database and compare to the current time.
  3. If the difference is under 2 seconds, terminate the script.
  4. Else, continue normally.

you can either use cookies (which can be disabled) so not a very good idea, or you can use store his ip address in the database, so if more then X tries from the same IP address then do not execute the code, just an if else statement, you will need a table with ip addresses time of request, number of tries

IF you do not want to use databases then you can use the following code

$file = "file.txt";
$file_content = file_get_contents($file);
$fh = fopen($file, 'w') or die("could not open file");
$now = time();
if($now - $file_content > 60){
// your code here
fwrite($fh, $now);
}else{
echo "Try again later";
}
fclose($fh);

but in this case, it won't be for each visitor but rather for all of them (so say user A came and execute the script, user B won't be able to execute it until 60 seconds pass.

The best way would be to store the time on serverside. If you leave the information on client side it would be easy to by pass.

I would for example save the timestamp in a table. That inputs and checks against spamming your script. And would be easy to set tolerence.

use either apc cache or mencache to store information storing to database or reading from file i believe is time/resource consuming

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!