Search code examples
phplimitexecution

Prevent PHP script from being flooded


I want to prevent my script, from being flooded - if user hit F5 it is executing the script every time.

I want to prevent from this and allow one script execution per 2 seconds, is there any solution for that?


Solution

  • 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 ) );
        }
    
    }