Подтвердить что ты не робот

Meteor.userId является изменяемым

Играя с Meteor, я обнаружил, что даже при снятом небезопасном пакете клиент может изменить функцию Meteor.userId. Например,

Meteor.userId=function() {return "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"}

как это можно сделать с помощью Meteor.default_connection.userId() (перенаправленная функция). Как защитить это?

4b9b3361

Ответ 1

Это отличный вопрос, потому что он показывает, как работает модель безопасности Meteor.

Здесь нет проблемы безопасности, поскольку Meteor никогда не доверяет клиентскому коду.

В Meteor только сервер решает, к каким данным каждый клиент имеет доступ (см. Meteor.publish) и какие данные каждому клиенту разрешено (см. Meteor.allow). Когда клиент аутентифицируется на сервере, сервер сохраняет идентификатор пользователя. Пока этот клиент не выйдет из системы, он предоставляет этот идентификатор вашим функциям Meteor.publish и Meteor.allow на сервере как userId.

Meteor также отправляет идентификатор пользователя на клиенте, потому что вы хотите изменить поведение клиента и то, что на экране, в зависимости от того, кто вошел в систему. И, как вы говорите, мы не можем остановить изгоев клиента от произвольного изменения любого из его кода JavaScript, чтобы изменить то, что он считает идентификатором пользователя! Но это не дает клиенту никаких новых разрешений, потому что по-прежнему остается только код сервера, который принимает решения о безопасности.

Вы можете попробовать это, используя приложение сторонних сторон:

  • Сделать приложение сторон с $ meteor create --example parties
  • Создайте учетную запись пользователя и дважды щелкните по карте, чтобы создать вечеринку. Установите флажок, чтобы сделать его частной стороной.
  • Откройте консоль JavaScript и введите Meteor.userId(), чтобы получить ваш идентификатор пользователя.
  • Выйдите из системы. Сторона исчезнет с экрана, потому что сервер не опубликует ее никому другому пользователю.
  • Теперь зайдите в консоль и перезапишите Meteor.userId() с помощью новой функции, которая возвращает нужный идентификатор.

Итак, теперь вы подделали клиента, чтобы думать, что это ваш пользователь. Но сервер знает лучше. На экране все еще не будет участника, и вы не сможете обновить коллекцию Party, чтобы изменить эту информацию.

На самом деле, совершенно безопасно устанавливать идентификатор пользователя клиента на все, что вы хотите! Вы можете войти в систему учетных записей и позвонить Meteor.default_connection.setUserId("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");. Попробуйте, и вы увидите, что кнопка входа в верхний правый угол превращается в анимацию. Это потому, что клиент вызывает Meteor.user(), чтобы отобразить адрес электронной почты только что зарегистрированного пользователя. Но поскольку вы не вошли на сервер в качестве этого пользователя, он не публикует какую-либо информацию об этом пользователе, и вы просто получаете спиннинг.

Это очень сильная модель безопасности. Вам не нужно беспокоиться о каком-либо клиентском коде, даже если в большинстве приложений, где проживает большая часть кода! До тех пор, пока вы пишете безопасные методы сервера, публикуете функции и разрешаете/запрещаете правила, вы полностью блокируетесь независимо от того, что клиент пытается сделать.

Ответ 2

Я только что протестировал Meteor, используя два браузера, и скопировал локальное хранилище Meteor.userId и Meteor.loginToken между каждым браузером, и оба они вошли в систему как один и тот же человек. Когда я вышел из одного, я все еще мог публиковать в другом.

Я не думаю, что это так же безопасно, как это делается.

Если я могу скопировать эти значения и по-прежнему рассматриваться как один и тот же пользователь, даже если я использую другой браузер, то он вообще не защищен.


Update

При отражении...

Я полагаю, что при входе в систему можно будет зарегистрировать IP-адрес пользователя. Затем, если пользователь пытается получить доступ, а IP-адрес не совпадает, вы можете попросить их снова войти в систему.