Phoenix sockets - connection spam

Googling socket security brings my 2 weeks old IP indentification thread as first result :slight_smile: can’t find any other relevant information / examples.

I am using guardian and only allowing authenticated users to connect but they can still spam it to infinity just by connecting and creating thousands of new processes, since there is no way to rate-limit(that I know of).

How are you guys securing your sockets/channels?

3 Likes

There are a variety of front-end proxy testers that can prevent such DOS’ing.

However, processes are cheap and processes for connections are very short lived (as long as you do not do anything long and costly in unauthenticated connections). You’d be surprised just how fast they process then vanish again (which is quite a fast operation too).

You can certainly limit open channels in many different ways.

A simplest thing that comes to mind is to have an Agent or an ETS table where you’re counting number of open channels per each socket, and then refuse new joins after some limit is reached. So in the join/3 callback you could do something like

def join(topic, message, socket) do
  ChannelCounter.bump(socket.assigns.client_id, self())

  if ChannelCounter.max_reached?(socket.assigns.client_id) do
    {:error, ...}
  else
    # proceed as normal
  end
end

Here, a ChannelCounter.bump should also setup a monitor to this channel, so it can reduce the counter if the channel process terminates. You could maybe use gproc counters to avoid doing that work.

Since join/3 is invoked inside a channel process, the channel process will still be briefly started, only to be terminated. I’m not sure how big of a problem that would be in practice, so it’s something that should be verified through an experiment.

3 Likes