Prevent PHP script from being flooded

后端 未结 5 2038
失恋的感觉
失恋的感觉 2020-12-01 15:43

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 pe

相关标签:
5条回答
  • 2020-12-01 16:09
    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.
    0 讨论(0)
  • 2020-12-01 16:16

    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.

    0 讨论(0)
  • 2020-12-01 16:16

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

    0 讨论(0)
  • 2020-12-01 16:17

    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.

    0 讨论(0)
  • 2020-12-01 16:19

    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 ) );
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题