8

Im implementing a delay system so that any IP i deem abusive will automatically get an incremental delay via Sleep().

My question is, will this result in added CPU usage and thus kill my site anyways if the attacker just keeps opening new instances while being delayed? Or is the sleep() command use minimal CPU/memory and wont be much of a burden on a small script. I dont wish to flat out deny them as i'd rather they not know about the limit in an obvious way, but willing to hear why i should.

[ Please no discussion on why im deeming an IP abusive on a small site, cause heres why: I recently built a script that cURL's a page & returns information to the user and i noticed a few IP's spamming my stupid little script. cURLing too often sometimes renders my results unobtainable from the server im polling and legitimate users get screwed out of their results. ]

lasavior
  • 141
  • 1
  • 5
  • I'd go with banning them on a higher level if possible (=less resource use), [this question on serverfault](http://serverfault.com/questions/287851/prevent-hammering-script-parsers) seems apt. – Wrikken Jul 26 '11 at 23:29
  • @Wrikken, This is not a segfault question, as the OP is asking how to code defensively against abusive users. – Soren Jul 26 '11 at 23:36
  • 1
    Didn't Jeff Atwood write something about this? It was called hellbanning or lagbanning or something. I'd be interested to learn how he was planning to implement it if he did go through with the decision without having a bajillion sleeping threads messing up the system. – Lotus Notes Jul 26 '11 at 23:38
  • While you specifically didn't want discussion on how you determine abusive user -- it sounds like the attack is rather "dumb" so have you considered to either just have an entry in robots.txt which bans crawling based on the Agent id? There are probably lots of stuff you can do for low quality abuse before you have to code anything. – Soren Jul 26 '11 at 23:39
  • @Soren: that was not what I was saying (otherwise, I would have voted for a move), I was just saying that would have been what _I_ would do, especially to limit resource usage. I was offering an alternative rather then an answer, perfectly suited for a comment, don't you think? – Wrikken Jul 26 '11 at 23:40
  • @Lotus: something like this probably: http://stackoverflow.com/questions/614795/simulate-delayed-and-dropped-packets-on-linux – Wrikken Jul 26 '11 at 23:43

4 Answers4

6

The sleep does not use any CPU or Memory which is not already used by the process accepting the call.

The problem you will face with implementing sleep() is that you will eventually run out of file descriptors while the attacker site around waiting for your sleep to time out, and then your site will appear to be down to any other people who tries to connect.

This is a classical DDoS scenario -- the attacker do not actually try to break into your machine (they may also try to do that, but that is a different storry) instead they are trying to harm your site by using up every resource you have, being either bandwidth, file descriptors, thread for processing etc. -- and when one of your resources are used up, then you site appears to be down although your server is not actually down.

The only real defense here is to either not accept the calls, or to have a dynamic firewall configuration which filters out calls -- or a router/firewall box which does the same but off your server.

Soren
  • 14,402
  • 4
  • 41
  • 67
5

I think the issue with this would be that you could potentially have a LARGE number of sleeping threads laying around the system. If you detect your abuse, immediately send back an error and be done with it.

My worry with your method is repeat abusers that get their timeout up to several hours. You'll have their threads sticking around for a long time even though they aren't using the CPU. There are other resources to keep in mind besides just CPU.

colithium
  • 10,269
  • 5
  • 42
  • 57
5

Sleep() is a function that "blocks" execution for a specific amount of time. It isn't the equivalent of:

while (x<1000000);

As that would cause 100% CPU usage. It simply puts the process into a "Blocked" state in the Operating System and then puts the process back into the "Ready" state after the timer is up.

Keep in mind, though, that PHP has a default of 30-second timeout. I'm not sure if "Sleep()" conforms to that or not (I would doubt it since its a system call instead of script)

Your host may not like you having so many "Blocked" processes, so be careful of that.

EDIT: According to Does sleep time count for execution time limit?, it would appear that "Sleep()" is not affected by "max execution time" (under Linux), as I expected. Apparently it does under Windows.

Community
  • 1
  • 1
Chris
  • 1,569
  • 2
  • 11
  • 18
1

If you are doing what I also tried, I think you're going to be in the clear.

My authentication script built out something similar to Atwood's hellbanning idea. SessionIDs were captured in RAM and rotated on every page call. If conditions weren't met, I would flag that particular Session with a demerit. After three, I began adding sleep() calls to their executions. The limit was variable, but I settled on 3 seconds as a happy number.

With authentication, the attacker relies on performing a certain number of attempts per second to make it worth their while to attack. If this is their focal point, introducing sleep makes the system look slower than it really is, which in my opinion will make it less desirable to attack.

If you slow them down instead of flat out telling them no, you stand a slightly more reasonable chance of looking less attractive.

That being said, it is security through a "type" of obfuscation, so you can't really rely on it too terribly much. Its just another factor in my overall recipe :)

VSack
  • 469
  • 1
  • 4
  • 11