Meteor 允许我从任何地方订阅,安全漏洞
Meteor allowing me to subscribe from anywhere, security flaw
所以我做了一个 meteor 应用程序,我删除了自动发布和不安全的包,现在为了从我的 collections 接收数据,我必须在客户端订阅它们。我还有一个 python 程序,它使用 python-meteor 包通过 ddp 与我的流星服务器通信,在其中我只是订阅了我的 collections 并且可以完全访问我的所有数据,我也可以使 Meteor.calls 调用服务器上的函数。这很好,但我忍不住觉得这是一个主要的安全漏洞,任何人都可以编写客户端并订阅我的 collections 并随心所欲地获取我的所有数据,如果他们猜到 collection 命名正确。
有没有办法只让某些客户端订阅 collection 并执行服务器调用?
是的,您应该对所有发布者和方法添加安全检查。
这是一个示例发布者,它确保用户在收到与该组相关的任何帖子之前已登录并且是该组的成员:
Meteor.publish('postsForGroup', function(groupId) {
check(groupId, String);
// make sure the user is a member of the group
var group = Groups.findOne(groupId);
if (!_.contains(group.members, this.userId))
throw new Meteor.Error(403, 'You must be a member of the group!');
return Posts.find({groupId: groupId});
});
这是一个示例方法,可确保用户在被允许更改组名称之前已登录并且是组的管理员:
Meteor.methods({
'groups.update.name': function(groupId, name) {
check(groupId, String);
check(name, String);
// make sure the user is an admin of the group
var group = Groups.findOne(groupId);
if (!_.contains(group.admins, this.userId))
throw new Meteor.Error(403, 'You must be an admin of the group!');
// make sure the name isn't empty
if (!name.length)
throw new Meteor.Error(403, 'Name can not be empty!');
return Groups.update(groupId, {$set: {name: name}});
}
});
需要注意的一个细节:如果您使用的是 Iron Router,请注意不要导致 发布商出现任何错误。这样做,将导致 waitOn
永远不会 return。如果您认为在正常操作下可能会抛出错误,那么我建议您在发布者中使用 return this.ready()
而不是 throw new Meteor.Error
。
所以我做了一个 meteor 应用程序,我删除了自动发布和不安全的包,现在为了从我的 collections 接收数据,我必须在客户端订阅它们。我还有一个 python 程序,它使用 python-meteor 包通过 ddp 与我的流星服务器通信,在其中我只是订阅了我的 collections 并且可以完全访问我的所有数据,我也可以使 Meteor.calls 调用服务器上的函数。这很好,但我忍不住觉得这是一个主要的安全漏洞,任何人都可以编写客户端并订阅我的 collections 并随心所欲地获取我的所有数据,如果他们猜到 collection 命名正确。
有没有办法只让某些客户端订阅 collection 并执行服务器调用?
是的,您应该对所有发布者和方法添加安全检查。
这是一个示例发布者,它确保用户在收到与该组相关的任何帖子之前已登录并且是该组的成员:
Meteor.publish('postsForGroup', function(groupId) {
check(groupId, String);
// make sure the user is a member of the group
var group = Groups.findOne(groupId);
if (!_.contains(group.members, this.userId))
throw new Meteor.Error(403, 'You must be a member of the group!');
return Posts.find({groupId: groupId});
});
这是一个示例方法,可确保用户在被允许更改组名称之前已登录并且是组的管理员:
Meteor.methods({
'groups.update.name': function(groupId, name) {
check(groupId, String);
check(name, String);
// make sure the user is an admin of the group
var group = Groups.findOne(groupId);
if (!_.contains(group.admins, this.userId))
throw new Meteor.Error(403, 'You must be an admin of the group!');
// make sure the name isn't empty
if (!name.length)
throw new Meteor.Error(403, 'Name can not be empty!');
return Groups.update(groupId, {$set: {name: name}});
}
});
需要注意的一个细节:如果您使用的是 Iron Router,请注意不要导致 发布商出现任何错误。这样做,将导致 waitOn
永远不会 return。如果您认为在正常操作下可能会抛出错误,那么我建议您在发布者中使用 return this.ready()
而不是 throw new Meteor.Error
。