note 52550 deleted from function.sleep by danbrown
| From: | danbrown@php.net | Date: | Sat, 14 Mar 2009 14:38:36 +0000 |
| Subject: | note 52550 deleted from function.sleep by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-151880@lists.php.net to get a copy of this message | ||
Note Submitter: tommiboy
----
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... :)