Prevent PHP Script from Being Flooded

Prevent PHP script from being flooded

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

}

How to stop people from flooding PHP API with requests?

You could serve a token generated and remembered on the server side which is rendered with your forms and validated when the form is sent back to your server. That prevents the user from just generating new post requests without actually requesting the according form from your server since they need the according token generated on your server to get it through.

Then there is the mentioned captcha which would be way too much for a login form from my point but when it comes to things like registering a new user the captcha in combination with the token sounds very good to me.

UPDATE
I Just found this article which is about floot protection of script execution in general. I think their approach is good as is the ip tracking provided you have the ability to use memcache or something similar to speed the checks up.

Quick and easy flood protection?

Use a token. You generate the token and add it to the page originating the request. In like.php you verify that the request contains a valid token, which means it comes from your page instead of an external one POSTing directly.

PHP: why does my flood prevention script lag?

When you open a session using session_start(), PHP locks the session file so any subsequent requests for the same session while another request has it open will be blocked until the session closes (you were exactly right with the "stacking" you suspected was happening).

You can call session_write_close() to close the session and release the lock but this probably won't help in this situation.

What's happening is each time the key is pressed, a request gets issued and each one is backed up while the previous one finishes, once the session is released one of the other requests opens the session and sleeps, and this keeps happening until they've all finished.

Instead, I'd create a global variable in Javascript that indicates whether or not a request is in progress. If one is, then don't send another request.

Something like this:

<script>
var requesting = false;

$('#input').on('keyup', function() {
if (requesting) return ;

requesting = true;
$.ajax({
url: "/url"
}).done(function() {
requesting = false;
});
}
</script>

ZipArchive class PHP security issue

Four your other questions:

floading

That's the complex part. Let me google you some ideas:

  • Prevent PHP script from being flooded
  • Quick and easy flood protection? - use a nonce, time+tie it onto a session
  • Use a captcha, if it doesn't impair usability too much.

uploading some kind of twisted exploit that would eventually alter my server
security

Use a commandline virus scanner (f-prot or clamav) to scan uploaded files. You might use a naive regex scanner in PHP itself (probe for HTMLish content in image files, e.g.), but that's not a factual security feature; don't reinvent the wheel.

buffer overflow

PHP in general is not susceptible to buffer overflows.

Okay, joking. But you can't do anything in userland about it. But pushing strings around isn't much of a problem. That's pretty reliable and unexploitable in scripting languages, as long as you know how to escape what in which context.

filenames that have arbitrary code injections

At the very leat you should most always use basename() to avoid path traversal exploits. If you want to keep user-specified filenames, a regex whitelist is in order. =preg_replace('/[^\w\s.]/', '', $fn) as crude example.



Related Topics



Leave a reply



Submit