Socket.io — Насколько безопасно управление их сеансами?

#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 бит лучше, но насколько лучше, может не иметь значения, и, следовательно, дополнительная работа может оказаться пустой тратой усилий, которые лучше потратить на другие вещи, в зависимости от того, что вы на самом деле пытаетесь защитить и как долго.