NanoHttpd / nanohttpd

Tiny, easily embeddable HTTP server in Java.
http://nanohttpd.org
BSD 3-Clause "New" or "Revised" License
6.95k stars 1.7k forks source link

"No Limit to Listen Threads" Possible security exploit? #86

Open ptcrash opened 10 years ago

ptcrash commented 10 years ago

Hello,

I've read through some of your code (though not all of it) and it appears you can have as many threads as the system will allow. Couldn't this be exploited into crashing the server? Or is there a way to limit however many connections can be made.

In an attempt to keep things secure, shouldn't there be a, for example, 50 simultaneous thread limit per IP? that way each legit requester will get what they want in a speedy fashion, but most malicious requester will not be as successful at DDOSing the server.

Thanks, MofuJofu

ritchieGitHub commented 9 years ago

Using a Executors would be a nice extension, anyone in for a pull request?

LordFokas commented 9 years ago

You only have 1 thread per session, and each session is bound to a socket, so in the current TCP/IP stack that means a hard limit of 65,536 "worker" threads.

AFAIK modern hardware and operating systems can handle that pretty well although probably slow.

When people talk about DDoS it seems to me they're just pulling out a fancy buzzword to mean flood attacks (and I don't mean you are doing it). Let's leave DDoS alone, it's not something everyone can pull off, it requires botnets and more-illegal-than-usual tricks you won't see script kiddies using. But let's talk about DoS. There are several forms of Denial of Service, among them Flooding and Slow Loris (my personal favorite). Slow Loris works a bit like Flooding, except instead of attempting to overload a server with data you abuse the Keep-Alive to lock as many ports / worker threads on the server as possible, which requires a lot less power because you can just send a single byte every 5 minutes to keep a socket alive and busy. While it may take some serious bandwidth or processing power to flood a server, if you lower the amount of workers it becomes a lot easier. If you were to lower the amount of threads to a hardcoded 50, any kid with a low-cost Android phone can lock the whole server down with a Slow Loris DoS attack.

And what I mean with this is, we should allow a limit to the amount of threads, but let the server administrator define how many. It's up to whoever is running NanoHTTPD to decide how many resources they want to sink into the server before it locks down. 25 or 50 threads seems like a decent limit on an Android phone, but if I were running NanoHTTPD in a beefy dedicated server I'd rather sink everything I've got into it until the server dies in a huge flood than allow any kid with a smartphone to DoS my application because I'm running on a 50 thread limit.

ritchieGitHub commented 8 years ago

I think it is the easiest to introduce the the thread pool in the refactored code. Or should we move this to 3.1.0?

LordFokas commented 8 years ago

You can change it at any point, I don't think it will have a significant impact on the code structure.

Using a thread pool seems like a great idea as it increases efficiency a lot... BUT it also leaves you vulnerable to Slow Loris and similar attacks unless you have more than one pool or some kind of security system that checks and categorizes request, which would be complex and a massive overhead.

This will invariably turn into a security vs efficiency debate.

ritchieGitHub commented 8 years ago

Yes, lets keep it simple and dynamic. I will introduce something simple like

startInThread(Runnable)

and the default just creates a thread. Subclasses can just use ThreadPools if they want to.