I am making a multiplayer game using socket.io. Here is a part of my server code.
io.on('connection', (socket) => {
console.log("socket has connected!!")
socket.on("go", (name) => {
addPlayer(name);
})
socket.on("move", (angle) => {
//do movement stuff
})
})
Now people are crashing my server by creating spam sockets. They are opening console and typing this code in client:
setInterval(() => {
var socket = io()
socket.emit("go", "haha ugothacked")
},10)
This creates 100 players each second and eventually crashes my server. How do I prevent this. I know you have to use some kind of rate limit. I don't know how to get ip of the socket.
I am using socket.io v4
How do I do this?
CodePudding user response:
You can make use of an anti spam library or make your own.
If you choose a library for that you could use: https://www.npmjs.com/package/socket-io-anti-spam
CodePudding user response:
Looking at https://socket.io/docs/v3/server-api/, you can use socket.handshake.address
to get the IP of the connecting client. After that you need to build up a server side array or object containing the ips along with the amount of requests they've made so you can build up a rate limiter and check how many requests they've made within the last minutes, you can also just completely block new requests from the same connection or things like creating a new player.
You can also force people to create an account and validate their email before playing your game, but that can be done in like 10 seconds using something like https://temp-mail.org/en/, so while it might be an extra layer of protection and slow them down, it won't prevent your issue.
You can also access the request headers in the request object, from that you can digitally fingerprint them. However a better solution, not to get into trouble with GDPR or violating people's privacy, is perhaps to store a uuid value as a cookie/localStorage and to have the client pass that as a request header. In that case they won't be able to just generate their own uuid and you can very purposefully target their uuid to rate limit/block them on socket events. However this is sort of the same thing as just using their IP in the first place.
I don't see a way you can achieve what you want without using some unique identifier, like an IP or a uuid, and building up a rate limiter server side. Other than that you can use a security service like cloudflare to rate limit for you, https://blog.cloudflare.com/cloudflare-traffic/, where you can rate limit on the auth token, among other things, but I think it won't work if you need to immediately block an event even on a second call (I don't know if their rules allow for that level of configuration).