473,225 Members | 1,368 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,225 software developers and data experts.

asyncore DoS vulnerability

Hi all. I've just terminated a server application using asyncore /
asynchat frameworks.
I wrote a test script that performs a lot of connections to the server
app and I discovered that asyncore (or better, select()) can manage
only a limited number of file descriptors (aka simultaneous
connections).
When this number is reached select() raises an error but asyncore
doesn't handle this exception (a crash occurs).
If you want to try this I pasted two scripts below: a server and a
client.
On my Windows XP system server.py the crash occurs when 512
simultaneous connections are reached.
Here's the traceback:

Traceback (most recent call last):
File "C:\Documents and Settings\root\Desktop\test.py", line 31, in ?
asyncore.loop(timeout=1)
File "C:\Python24\lib\asyncore.py", line 192, in loop
poll_fun(timeout, map)
File "C:\Python24\lib\asyncore.py", line 122, in poll
r, w, e = select.select(r, w, e, timeout)
ValueError: too many file descriptors in select()
Why does this exception isn't handled inside asyncore.py?

----------------------------------------------------
# server.py
import asyncore, socket

class server(asyncore.dispatcher):
"""The base class for the backend."""

def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(('', 8080))
self.listen(5)

def handle_accept(self):
sock_obj, addr = self.accept()
handler(sock_obj)

class handler(asyncore.dispatcher):

def __init__(self, sock_obj):
asyncore.dispatcher.__init__(self, sock=sock_obj)

def handle_write(self):
pass

def handle_read(self):
pass

server()
asyncore.loop(timeout=1)

-----------------------------------------------------

# client.py
import socket, threading, os

def client():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(("127.0.0.1", 8080))
except:
print x
os._exit(0)
while 1:
s.recv(1024)

x = 0
while 1:
x +=1
threading.Thread(target=client).start()
print x

Feb 1 '07 #1
7 2704
On Thursday 01 February 2007, billie wrote:
Here's the traceback:

Traceback (most recent call last):
File "C:\Documents and Settings\root\Desktop\test.py", line 31, in ?
asyncore.loop(timeout=1)
File "C:\Python24\lib\asyncore.py", line 192, in loop
poll_fun(timeout, map)
File "C:\Python24\lib\asyncore.py", line 122, in poll
r, w, e = select.select(r, w, e, timeout)
ValueError: too many file descriptors in select()
I just tried this on 64bit kubuntu edgy and this is what I got

<snip lots of numbers>
1019
1020
Exception in thread Thread-1021:
Traceback (most recent call last):
File "threading.py", line 442, in __bootstrap
File "threading.py", line 422, in run
File "client.py", line 5, in client
File "socket.py", line 148, in __init__
error: (24, 'Too many open files')

1021
Exception in thread Thread-1022:
Traceback (most recent call last):
File "threading.py", line 442, in __bootstrap
File "threading.py", line 422, in run
File "client.py", line 5, in client
File "socket.py", line 148, in __init__
error: (24, 'Too many open files')

Exception in thread Thread-1020:
Traceback (most recent call last):
File "threading.py", line 442, in __bootstrap
File "threading.py", line 422, in run
File "client.py", line 12, in client
error: (104, 'Connection reset by peer')

1022
1023
Feb 2 '07 #2
Did you take a look for "too many file descriptors in select()" on
google.

On 1 fév, 20:18, "billie" <gne...@gmail.comwrote:
Hi all. I've just terminated a server application using asyncore /
asynchat frameworks.
I wrote a test script that performs a lot of connections to the server
app and I discovered that asyncore (or better, select()) can manage
only a limited number of file descriptors (aka simultaneous
connections).
I thing this is the system that limit the number of open sockets or
select() list
When this number is reached select() raises an error but asyncore
doesn't handle this exception (a crash occurs).
This is not a CRASH, It looks an exception with a "Traceback", this is
the normal way python report problems, nothing wrong with that.
You can handle it with a try: except:
If you want to try this I pasted two scripts below: a server and a
client.
On my Windows XP system server.py the crash occurs when 512
simultaneous connections are reached.
512 is probably a fixed limit into XP, win2k3 or win2k server will
accept more.
Maybe It's possible to increase this value somewhere in the registry.
If not this is how microsoft justify the difference between server and
workstation products :-)
Here's the traceback:

Traceback (most recent call last):
File "C:\Documents and Settings\root\Desktop\test.py", line 31, in ?
asyncore.loop(timeout=1)
File "C:\Python24\lib\asyncore.py", line 192, in loop
poll_fun(timeout, map)
File "C:\Python24\lib\asyncore.py", line 122, in poll
r, w, e = select.select(r, w, e, timeout)
ValueError: too many file descriptors in select()

Why does this exception isn't handled inside asyncore.py?
To do what ? To raise a custom asyncore error ?
You can can probably run over this limit by starting multiple of your
server process (not thread, process) .
>
----------------------------------------------------
# server.py
import asyncore, socket

class server(asyncore.dispatcher):
"""The base class for the backend."""

def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(('', 8080))
self.listen(5)

def handle_accept(self):
sock_obj, addr = self.accept()
handler(sock_obj)

class handler(asyncore.dispatcher):

def __init__(self, sock_obj):
asyncore.dispatcher.__init__(self, sock=sock_obj)

def handle_write(self):
pass

def handle_read(self):
pass

server()
asyncore.loop(timeout=1)

-----------------------------------------------------

# client.py
import socket, threading, os

def client():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(("127.0.0.1", 8080))
except:
print x
os._exit(0)
while 1:
s.recv(1024)

x = 0
while 1:
x +=1
threading.Thread(target=client).start()
print x

Feb 2 '07 #3
This is not a CRASH, It looks an exception with a "Traceback", this is
the normal way python report problems, nothing wrong with that.
You can handle it with a try: except:
I think that such a thing should be handled by asyncore itself.
512 is probably a fixed limit into XP, win2k3 or win2k server will
accept more.
Maybe It's possible to increase this value somewhere in the registry.
If not this is how microsoft justify the difference between server and
workstation products :-)
Yeah, maybe...
>Why does this exception isn't handled inside asyncore.py?
To do what ? To raise a custom asyncore error ?
asyncore aims to be a framework, right?
I think that when select() limit is reached asyncore should just drop
other connections. That's all.
You can can probably run over this limit by starting multiple of your
server process (not thread, process).
Hope you're joking...
Why should I have to run multiple processes / threads to avoid such a
problem?
And what if my system / inteprepter does not support multiple
processes / threads?

Feb 2 '07 #4
On 2 Feb 2007 07:32:14 -0800, billie <gn****@gmail.comwrote:
This is not a CRASH, It looks an exception with a "Traceback", this is
the normal way python report problems, nothing wrong with that.
You can handle it with a try: except:

I think that such a thing should be handled by asyncore itself.
Handled by doing what, exactly?
512 is probably a fixed limit into XP, win2k3 or win2k server will
accept more.
Maybe It's possible to increase this value somewhere in the registry.
If not this is how microsoft justify the difference between server and
workstation products :-)

Yeah, maybe...
Why does this exception isn't handled inside asyncore.py?
To do what ? To raise a custom asyncore error ?

asyncore aims to be a framework, right?
I think that when select() limit is reached asyncore should just drop
other connections. That's all.
Silently rejecting connections in a way that is invisible to the
application is clearly the wrong thing to do.
>
You can can probably run over this limit by starting multiple of your
server process (not thread, process).

Hope you're joking...
Why should I have to run multiple processes / threads to avoid such a
problem?
Thats like asking why you should have to move your fingers to type or
why you should have to eat food in order to not starve. Windows is
placing a limit of 512 descriptors per process. Call Microsoft if you
want to go over that.

Or, you can volunteer to write a win32 port of asyncore that uses
native winsock functions instead of the BSD compatibility functions.
And what if my system / inteprepter does not support multiple
processes / threads?
What if it doesn't support sockets? This is a platform limitation, not
an arbitrary Python one. Nothing Python is going to do is going to
convince Windows to select() on more than 512 file descriptors per
process.
Feb 2 '07 #5

billieasyncore aims to be a framework, right? I think that when
billieselect() limit is reached asyncore should just drop other
billieconnections. That's all.

You're asking asyncore to make a policy decision on behalf the controlling
application. It has no idea what that application wants to do when the open
file limit is reached. Maybe it should close the oldest connection instead
of refusing all new ones. Maybe it should adjust the rate at which it
accepts new connections. asyncore doesn't know.

Skip
Feb 2 '07 #6
On 2 Feb, 17:09, "Chris Mellon" <arka...@gmail.comwrote:
Thats like asking why you should have to move your fingers to type or
why you should have to eat food in order to not starve. Windows is
placing a limit of 512 descriptors per process. Call Microsoft if you
want to go over that.
?
That's not a select() problem: that's an asyncore problem.
I'm just saying that asyncore should handle this event in some other
way than raising a not well defined "ValueError".
I've discovered this problem accidentally by writing a small test
script but personally I've never seen a paper describing it.
Not handling such a problem just means that an asyncore based server
is vulnerable to DoS attacks and I believe that a lot of servers out
there didn't used a try/except statement around "asyncore.loop()".
imho, such a problem should merit some attention.
Don't you agree?

Feb 3 '07 #7
On 2 fév, 16:32, "billie" <gne...@gmail.comwrote:
Why does this exception isn't handled inside asyncore.py?
To do what ? To raise a custom asyncore error ?

asyncore aims to be a framework, right?
I think that when select() limit is reached asyncore should just drop
other connections. That's all.
Nice idea.
It shoul be nice to be able to limit the number of connections
asyncore can manage, to say,
limit the load of the server, or in your case tell asyncore you are
working on a poor platform :-)

Then asyncore could call a user defined function (a policy) when this
limit is reached.
This function could interact with asyncore to take an action: reject
the connection, close idle connections .....

You could try to persuade asyncore developers to include this feature.

You can can probably run over this limit by starting multiple of your
server process (not thread, process).

Hope you're joking...
Why should I have to run multiple processes / threads to avoid such a
problem?
And what if my system / inteprepter does not support multiple
processes / threads?
I was just giving a possible workaround.

Feb 4 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Michael Welsh | last post by:
In order to learn sockets in Python I am trying to write a simple group chat server and client. I need a little nudge, please. My question contains some GUI but only as decoration. The root...
5
by: David M. Wilson | last post by:
Hi peeps, I finally got around recently to doing something serious using Python for serving network clients asynchronously, deciding on asyncore as my starting point. After 2 days or so of...
2
by: Freddie | last post by:
Hi, I've been mangling python-irclib into an asyncore class, so it fits in nicely with the rest of my app. I ran into a problem with asyncore.dispatcher_with_send (Python 2.3.4), though. Not...
0
by: Neil Benn | last post by:
Hello, I was wondering if someone could provide assistance. I'm writing a thin wrapper around asyncore for compatibility with a common Comms API that I use. class...
3
by: Anand Pillai | last post by:
This is for folks who are familiar with asynchronous event handling in Python using the asyncore module. If you have ever used the asyncore module, you will realize that it's event loop does not...
0
by: Tony Meyer | last post by:
Changes in asyncore from 2.3 to 2.4 mean that asyncore.poll() now passes all the sockets in the map to select.select() to be checked for errors, which is probably a good thing. If an error occurs,...
3
by: Jos | last post by:
Hello. I'm using the asyncore and _chat modules to create a network server. I also have, running in a separate thread(s), a "producer" which needs to "push" data onto the network connection(s)....
5
by: JamesHoward | last post by:
I have a problem with python's asyncore module throwing a bad file descriptor error. The code might be difficult to copy here, but the problem is essentially: The server wants to sever the...
0
by: Giampaolo Rodola' | last post by:
Hi, I post this message here in the hope someone using asyncore could review this. Since the thing I miss mostly in asyncore is a system for calling a function after a certain amount of time, I...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.