Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic flood detection #8

Open
josephernest opened this issue Nov 22, 2016 · 3 comments
Open

Basic flood detection #8

josephernest opened this issue Nov 22, 2016 · 3 comments

Comments

@josephernest
Copy link
Owner

josephernest commented Nov 22, 2016

Rough idea:

On connect of a new client ws :

 bytesent[ws] = 0

We should do this each time a message is posted by a user ws :

 bytesent[ws] += len(message)

Then we should measure if the increase is more than, say, 1kB per minute. If so deconnect, and store the IP of the potential spammer.

If user comes back and second flood, add to IP ban list...

Something else: how to get IP from ws here with websocket: https://github.com/josephernest/talktalktalk/blob/master/talktalktalk.py#L75 ?

@29d
Copy link

29d commented Nov 22, 2016

You can get the IP address from request headers.

ip = request.headers.get('X-REAL-IP') or request.headers.get('HOST')

The correct header will depend on the webserver or proxy you are running behind.

How are you going to calculate the kB per minute with only the length sent? Check the length every minute or X seconds?
What about something like:

from collections import deque

# on ws connect:
rate_limit[ws] = deque(maxlen=10)

# on ws message:
rate_limit[ws].append(time.time())
if len(rate_limit[ws]) = rate_limit[ws].maxlen:
    if time.time() - rate_limit[ws][0] < 1:
        break

Rate limit user messages to 10 messages a second. Drop the excess messages. Alternatively you could disconnect a user instead.

@josephernest
Copy link
Owner Author

I agree with that solution @29d. Would you do a pull request? If so, I'll merge it.

@josephernest
Copy link
Owner Author

josephernest commented Nov 25, 2016

Thanks @29d . I added your flood control method (to be merged in a few minutes).

About IP, I tested on 2 servers (Server1: Apache proxy forwarding to Python ; Server2: a VPS with direct access). Here are the results:

request.headers.get('X-REAL-IP')             #  'None' with Server1 ; 'None' with Server2
request.headers.get('HOST')                  #  localhost:9000 with Server1 ; IP the server itself with Server2 
request.environ.get('HTTP_X_FORWARDED_FOR')  #  correct client IP with Server1 ; 'None' with Server2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants