#node.js #session #socket.io
#node.js #сеанс #socket.io
Вопрос:
В настоящее время я разрабатываю веб-приложение и хотел бы внедрить в него некоторые базовые меры безопасности. В контексте этого я расследую, подходит ли ванильный сокет.io, используемый для обработки сеансов с пользователями, безопасен. Из этой статьи я узнал, что для каждого сокета подключения.io получает его, генерирует идентификатор (даже если это просто новая вкладка браузера). Я думаю, это можно рассматривать как очень простой идентификатор сеанса. Теперь мой вопрос в том, как генерируется этот идентификатор и достаточно ли он случайный, чтобы никто не мог перехватить сеанс, угадав (будь то методом перебора или какой-либо статистикой) такой идентификатор активного пользователя?
Поскольку некоторые люди просили разъяснений: я пытаюсь избежать захвата сеанса злоумышленником. Будь то из-за того, что злоумышленник может легко перебирать идентификаторы сеансов, угадайте это, используя некоторые статистические данные из-за того, что он недостаточно случайный или может украсть его с помощью сетевого прослушивания / XSS, чтобы украсть файл cookie, в котором он хранится.
Комментарии:
1. «некоторые основные меры безопасности» очень общий. Что именно вы пытаетесь сделать и от чего именно вы хотите защитить?
2. Добавлено уточнение.
3. Чтобы снова защитить перехват сети, вы ДОЛЖНЫ использовать HTTPS. Это общее для всего транспорта, а не только для socket.io .
4. Да, я уверен, что HTTPS. Что касается XSS, я также проверил, что файл cookie использует флаг HttpOnly.
Ответ №1:
Из вашего вопроса неясно, какую «безопасность» вы пытаетесь реализовать или от чего пытаетесь защитить. Что касается идентификатора сеанса, вот как он генерируется, а затем вы можете решить, соответствует ли это вашим потребностям или нет.
Во-первых, розетка.io использует метод, вызываемый .generateId()
для создания нового идентификатора. У него есть реализация по умолчанию (к которой мы перейдем через секунду), но вы также можете заменить ее своим механизмом, если хотите, согласно документу здесь.
Тогда вот реализация по умолчанию:
generateId(req) {
return base64id.generateId();
}
который, очевидно, просто вызывает модуль base64id, который использует этот код:
Base64Id.prototype.generateId = function () {
var rand = Buffer.alloc(15); // multiple of 3 for base64
if (!rand.writeInt32BE) {
return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString()
Math.abs(Math.random() * Math.random() * Date.now() | 0).toString();
}
this.sequenceNumber = (this.sequenceNumber 1) | 0;
rand.writeInt32BE(this.sequenceNumber, 11);
if (crypto.randomBytes) {
this.getRandomBytes(12).copy(rand);
} else {
// not secure for node 0.4
[0, 4, 8].forEach(function(i) {
rand.writeInt32BE(Math.random() * Math.pow(2, 32) | 0, i);
});
}
return rand.toString('base64').replace(///g, '_').replace(/ /g, '-');
};
При запуске сервера на nodejs, где crypto
существует модуль, это вызовет this.getRandomBytes()
, и этот код будет включен в тот же модуль, который вы можете посмотреть. Он использует crypto.randomBytes(12)
.
Затем вы можете сами решить, соответствует ли это вашим потребностям в безопасности. Или вы могли бы заменить его другим генератором идентификаторов, который соответствовал вашим потребностям. К вашему сведению, случайное число размером 12 байт довольно сложно угадать. Это 256, увеличенное до 12-го размера пространства идентификаторов. 256 ^ 12 равно 7.9228163e 28.
Комментарии:
1. Привет, спасибо за ваш ответ! Я добавил разъяснение о том, от чего я именно хочу защититься. Я прочитал эту статью о том, как долго идентификатор сеанса должен быть минимальным, чтобы считаться «безопасным». Это предполагает 128 бит длины, в то время как сокет. io, похоже, генерирует идентификаторы длиной 96 бит. Вы считаете, что они немного преувеличивают, и 96 должно быть достаточно, чтобы не требовать полного изменения этого кода?
2. @Astarno — Это действительно зависит от того, что поставлено на карту и как долго у вас будет постоянный сеанс. Что касается паролей к моим финансовым счетам, я бы придерживался немного другого стандарта, чем моя игровая сессия. 96 бит — это довольно хорошо. 128 бит лучше, но насколько лучше, может не иметь значения, и, следовательно, дополнительная работа может оказаться пустой тратой усилий, которые лучше потратить на другие вещи, в зависимости от того, что вы на самом деле пытаетесь защитить и как долго.