Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delaying execution of PHP script

What is the best way to stop bots, malicious users, etc. from executing php scripts too fast? Is it ok if I use the usleep() or sleep() functions to simply do "nothing" for a while (just before the desired code executes), or is that plain stupid and there are better ways for this?

Example:

function login() {
 //enter login code here
}

function logout() {
 //enter logout code here
}

If I just put, say, usleep(3000000) before the login and logout codes, is that ok, or are there better, wiser ways of achieving what I want to achieve?

edit: Based on the suggestions below, does then usleep or sleep only cause the processor to disengage from the current script being executed by the current user, or does it cause it to disengage from the entire service? i.e. If one user+script invokes a sleep/usleep, will all concurrent users+scripts be delayed too?

like image 333
Mussnoon Avatar asked Feb 01 '09 05:02

Mussnoon


2 Answers

The way most web servers work (Apache for example) is to maintain a collection of worker threads. When a PHP script is executed, one thread runs the PHP script.

When your script does sleep(100), the script takes 100 seconds to execute.. That means your worker thread is tied up for 100 seconds.

The problem is, you have a very finite number of worker-threads - say you have 10 threads, and 10 people login - now your web-server cannot serve any further responses..

The best way to rate-limit logins (or other actions) is to use some kind of fast in-memory storage thing (memcached is perfect for this), but that requires running separate process and is pretty complicated (you might do this if you run something like Facebook..).

Simpler, you could have a database table that stores user_id or ip_address, first_failed and failure_counter.

Every time you get a failed login, you (in pseudo code) would do:

if (first_failed in last hour) and (failure_counter > threshold):
    return error_403("Too many authentication failures, please wait")
elseif first_failed in last hour:
    increment failure_counter
else:
    reset first_failed to current time
    increment failure_counter

Maybe not the most efficient, and there is better ways, but it should stop brute-forcing pretty well. Using memcached is basically the same, but the database is replaced with memcached (which is quicker)

like image 158
dbr Avatar answered Oct 02 '22 18:10

dbr


to stop bots, malicious users, etc. from executing php scripts too fast?

I would first ask what you are really trying to prevent? If it is denial-of-service attacks, then I'd have to say there is nothing you can do if you are limited by what you can add to PHP scripts. The state of the art is so much beyond what we as programmers can protect against. Start looking at sysadmin tools designed for this purpose.

Or are you trying to limit your service so that real people can access it but bots cannot? If so, I'd look at some "captcha" techniques.

Or are you trying to prevent users from polling your site every second looking for new content? If so, I'd investigate providing an RSS feed or some other way of notifying them so they don't eat up your bandwidth.

Or is it something else?

In general, I'd say neither sleep() nor usleep() is a good way.

like image 45
bmb Avatar answered Oct 02 '22 18:10

bmb