Безопасность в websockets. Возможно ли отфильтровать все соединения на уровне handshake и отключить атаки злоумышленника?
Как обезопасить соединение по ws?
1. Проверка origin.
Тем самым можно запретить подключаться с разных доменов, протоколов и тп
Но как быть, если подключение ведется с разрешенного домена, но отправка пакетов осуществляется злоумышленником?
Как это сделать:
В любом браузере есть консоль. Зайдя в нее и находясь на разрешенной странице, можно создать через нее новое подключение и посылать пакеты вручную, тем самым завалить сервер, например, синтаксической атакой.
Как этого избежать?
Можно проверять каждое сообщение message. Такая проверка будет осуществляться для каждого пакета, каждого юзера. А если пакетов много (онлайн игра) и юзеров много, то это создает дополнительную нагрузку!
При это если проект опенсорсный, то всегда есть возможность покопаться в исходниках и наверняка найти дыру
Думаю самый правильный вариант - фильтровать соединения на момент рукопожатия (handshake).
Вот только как это сделать?
А еще до прихода пакетов не хотите фильтровать? А ведь их есть у нас, тогда смотрите в cторону Application Layer Gateway, например хардварный F5 или встроенные в ОС софтварные реализации или проксирующие типа nginx, да еще и с терминацией SSL. А в ноде авторизация происходит после открытия соединения. Чтобы отфильтровать, нужно уже иметь открытый сокет, IP-адрес, распарсенный HTTP-заголовок, вынутые из него кукизы, в частности, идентификатор сессии.
Если в ноде, то я выше написал первое место, где можно отловить, а если до ноды, то я в предыдущем комменте описал. Вы кажется хотите отловить запрос еще не распарсив заголовки, по тем полям которые находятся в заголовках, это сделать ни как не возможно.
я хочу отловить запрос! неважно на каком этапе. То что заголовки мне в этом не помогут, это да!
а как мне поможет это:
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
что там приходит в request? и как мне определить что подключение идет из консоли?
сейчас я использую https://github.com/einaros/ws
Определить origin не проблема! А вот определить что соединение установила программа, а не злоумышленник я уже не могу!
Он зайдет на мой сайт (origin будет валидный) и через консоль подрубится к вебсокетам. Отправит пару пакетов и положит сервер))
При чем тут вообще консоль? При чем тут origin, он на той же ноде сделает клиента, который положит сервер. Понять, будет это браузер или клиент на ноде (или на любом другом языке) или человек из консоли - практически невозможно, нужно защищать функциональность и делать обработку сокета устойчивой к таким шутникам. Иначе ни как.