|
|
 |
sleep (PHP 3, PHP 4, PHP 5) sleep -- Delay execution Descriptionvoid sleep ( int seconds )
The sleep() function delays program execution for the
given number of seconds.
Example 1. sleep() example |
<?php
echo date('h:i:s') . "\n";
sleep(10);
echo date('h:i:s') . "\n";
?>
|
This example will output (after 10 seconds)
|
See also usleep() and
set_time_limit()
User Contributed Notes
sleep
tommiboy
11-May-2005 06:43
Two additions to my previous note:
1. You can of course *always* run a DoS on any server at any time. If you have a few hundred hijacked machines, then you can incapacitate even huge sites like amazon or worldpay who have really large resources, as has been done before. Unluckily, there is not much you can do against braindead crimials. Even if you block them on the IP layer, they can still fill the wire with datagrams :(
However, sleep() makes an attack a lot cheaper. If the target uses for example sleep(5); then the attacker can safely assume that one request will keep one process running for 5 seconds.
So, only a few dozen requests (w/ dropped connections), will safely run you into "MaxClients" and you will not be able to accept legitimate requests any more. So what, increase "MaxClients" then, I hear you say? The attacker can do this for hours, but you can't...
10MB of memory for a server process is not a unreasonable assumption. If your web server has 2GB of RAM then it will start thrashing after starting 200 processes. A 32 bit machine is out of virtual memory after 400. That can be achieved using a 14.4k modem...
2. The <FilesMatch> rule in my example is flawed as it opens access to config files. By mere coincidence (due to another rule), it has been working fine for a year and a day on my machine, so I never noticed until now.
It is still a bad mistake. Use your login form's filename rather than "^.*$".
tommiboy
05-May-2005 09:33
Using sleep() to slow down intruders is a very bad idea since it keeps your httpd running.
If someone realizes that you are using sleep(), then he can very easily run a DoS on your server.
All he needs to do is run a few hundred threads sending login requests. Worse, he could even do this in a single thread as long as he sends requests more frequently than you return from sleep(). He can drop the connection, it doesnt matter while you sleep().
This attack is very cheap regarding bandwidth, cpu, and memory consumption. Contrarily, on your server, the number of httpd instances is limited, when your server reaches the hard limit, legitimate clients will be dropped. Also, a server instance consumes at least a few megabytes of memory, and fork()ing is not free, either.
A much better solution, in my opinion, is to auto-blacklist intruders after 5 or so wrong password challenges. Admitted... auto-blacklisting is somewhat awkward, too, for three reasons:
1. It requires a script to modify .htaccess files. Most people feel a pain in their groin when even thinking about this.
2. An attacker who realizes that you auto-blacklist could exploit the fact that http does not need a tcp connection and send single datagrams with spoofed source addresses, thus having you blacklist arbitrary ip addresses (big ouch).
3. Might blacklist innocent people (dynamic ip adress?? user is too stupid to enter pass??)
Problem 1 should not be a concern. If someone can insert arbitrary content through any of your scripts, then you have a major security hole elsewhere. Having .htaccess set to read-only won't help you in that case. This opinion may be objectionable, but for me, it is fine to have .htaccess modified by a script.
Problem 2 can be avoided by either using SSL (big performance ouch!) or by starting a session prior to the login form. Since PHP is nice enough to verify sessions against ip addresses, an attacker must know a valid session as well as the corresponding ip address to be able to spoof that address, hence he must at least receive one data packet, so the address cannot be spoofed quite so easily.
Problem 3 is eleminated by running a cron job that occasionally (like every 5 mins) deletes items from the blacklist.
There are several ways to do the blacklisting, this is one: prepend "SetEnvIf Remote_Addr $_SERVER['REMOTE_ADDR'] blacklist" to a .htaccess file that contains a
<FilesMatch "^.*$">
order deny,allow
deny from env=blacklist
</FilesMatch>
rule. Only denying the login form would of course be sufficient, too, but I see no reason not to deny all :)
This is rather primitive, but good enough for my needs and very efficient (better than mod_rewrite, and better than two dozen deny rules).
Another (crazy) idea would of course be to run httpd as root and call iptables from php, but you really need big bollocks to do that... :)
BrianKStein at gmail dot com
07-Mar-2005 05:11
In response to the posts below about security, you could set a MySQL or Text record using the IP address that was logging in and then the login script would ban anyone who didn't wait the full sleep time because their IP would be in a temporary ban list and their name would only be deleted from that by a command after the sleep command.
<?php
echo "One moment while we check your username and password. DO NOT press the back button on your browser.";
sleep(5); ?>
MPHH
05-Jul-2003 02:33
Note: The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), the sleep() function, database queries, etc. is not included when determining the maximum time that the script has been running.
cet [at] carlthompson [dot] net
24-Jun-2003 08:10
About using sleep() after an authentication failure:
While it is true that crackers can launch multiple concurrent attempts, the number of concurrent attempts is limited to your server's maximum number of concurrent requests. As this number is usually miniscule in comparison to the numbers of attempts a cracker would probably need to brute force a password, sleep() _does_ in fact provide effective anti-cracking benefit.
Of course, a smart cracker could write his code to end the connection long before the sleep() is done, but that makes it a guessing game; how quickly can the connection be ended without accidently losing the successful connections the cracker wants? This is not an easy question to answer for the cracker because all of those concurrent connection attempts can significantly slow down all of the responses, even successful ones. Against this "smart" cracker there is going to be a limit; sleep(30) is probably going to be no more effective than sleep(5). In the end, using sleep() makes the code neccessary to brute force a password much more complicated and that in itself will eliminate some would-be crackers. For the others, it does slow them down somewhat.
So the short answer is that using sleep() after an authentication failure is _always_ better than not using sleep().
Best of all is to use sleep() after successful authentication too-- this would mean that the cracker _must_ wait the full sleep() period in every case and makes brute forcing a password require a very, very long time (years?). This probably wouldn't even bother users that much as it would only happen once per login.
Jonesy (at) jonz dot net
15-Apr-2003 02:52
To add to Josh's observation: A hack to accomplish the "slow-the-bastards-down" logic would be to flock a `cracker-control-file` going into the sleep operation.<br>
Crackers ain't the only ones that can use multi-threading tactics.
josh at NO chatgris SPAM dot com
27-Jan-2003 06:33
Contrary to previous posts, sleep provides not security whatsoever against crackers. They can quite easily create a multithreaded program that will try 1000 passwords at a time effectively disabling your sleep pause, and sessions don't help as each a request can make itself look like a new session. The only way to make this effective at all is to store the last time a user attempted to login in a database and onyl allow x tries per time period.
hartmut at six dot de
25-Aug-2000 08:38
it is a bad idea to use sleep() for delayed output effects as
1) you have to flush() output before you sleep
2) depending on your setup flush() will not work all the way to the browser as the web server might apply buffering of its own or the browser might not render output it thinks not to be complete
netscape for example will only display complete lines and will not show table parts until the </table> tag arrived
so use sleep if you have to wait for events and don't want to burn to much cycles, but don't use it for silly delayed output effects!
| |