J'ai appris récemment node.js et socket.io. Ma question est de savoir comment puis-je protéger le serveur contre les attaques côté client?
Ceci est mon code serveur
io.sockets.on('connection', function (socket) {
//users.Push(socket);
socket.on('message', function (data) {
socket.on('disconnect', function () { });
socket.on('bcast', function (data) {
socket.emit('news', { 'data': data });
socket.broadcast.emit('news', { 'data': data });
});
socket.on('login', function(data){
socket.emit('login', {'data': [ socket.id, data ] });
});
});
});
Par exemple, si un client utilise chrome outils de développement pour faire le code fluide
for(var i = 0; i<99999999999; i++)
{
socket.emit('bcast', {data: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'});
}
ça va tuer le serveur.
Regardez dans la limitation et le rebond d'événement JS!
Ces techniques vous aideront à prévenir et détecter les attaques jusqu'à un certain point (ce qui est, à mon avis, suffisant pour un petit jeu de socket multijoueur) ...
ÉDITER:
Dans ce jsfiddle: http://jsfiddle.net/y4tq9/9/
var sIO = {};
sIO.on = (function(){
var messages = {};
var speedLimit = 5; //5ms
return function(message, handler) {
messages[message] = messages[message] || {};
if(messages[message].timestamp && new Date().getTime() - messages[message].timestamp < speedLimit) return false;
else messages[message].timestamp = new Date().getTime();
handler();
return true;
//execute code, Ex:
}
}());
vous pouvez voir que chaque demande envoyée plus rapidement que 5 ms retournera false, sinon le gestionnaire sera exécuté.
Vous déconnectez simplement les sockets qui envoient la requête plus vite que 5ms (ou 2ms, ou 3ms selon votre réseau et le poids de votre application ...).
Vous pourriez aussi bien utiliser la limitation d'événements js sur le site client pour vous assurer que toutes vos demandes ne sont pas envoyées plus vite que la limite de vitesse!
Cette technique ne fournira pas une protection absolue contre l'exploitation, mais elle empêchera votre serveur de se bloquer lorsque les attaquants tentent de Dos ...
Le package rate-limiter-flexible Node.js peut être utilisé contre les attaques DDoS.
const { RateLimiterMemory } = require('rate-limiter-flexible');
const rateLimiter = new RateLimiterMemory({
points: 5, // 5 points
duration: 1 // per second
});
socket.on('bcast', data => {
rateLimiter.consume(uniqueSocketId) // consume 1 point per event
.then(() => {
socket.emit('news', { 'data': data });
socket.broadcast.emit('news', { 'data': data });
})
.catch(rejRes => {
// no available points to consume
// emit error or another workaround
});
});
Tout événement sera bloqué s'il se produit plus de 5 fois par seconde.
Il existe également l'option pour les applications distribuées utilisant Redis. Et certains paramètres flexibles comme l'assurance et la stratégie de blocage font de rate-limiter-flexible
hautement disponible et rapide.
Ce n'est pas toujours une bonne idée de le faire sur votre serveur http. Vérifiez cette réponse: Comment empêcher les attaques DOS sur mon serveur http qui a écrit dans node.js?
Étant donné que le nœud n'est pas le "meilleur" pour gérer de telles conditions DDoS dans le cadre lui-même, j'examinerais les tactiques d'atténuation DDoS de troisième partie telles que cloudflare ou blacklotus. Ce sont des offres coûteuses si vous avez une grande échelle d'utilisation, mais elles protégeront Node ou vraiment n'importe quel framework contre les attaques par déni de service).
Une autre option consiste à utiliser des solutions de pare-feu basées sur des logiciels comme aiProtect, qui sont un peu plus rentables lors de la mise à l'échelle au-delà du niveau gratuit de cloudflare et blacklotus.
http://aiscaler.com/home/protect
Il y en a beaucoup plus, mais celui-ci a un partenariat AWS afin que vous puissiez facilement faire tourner les machines virtuelles aiProtect.