【问题标题】:How to prevent invoking 'Meteor.call' from JavaScript Console?如何防止从 JavaScript 控制台调用“Meteor.call”?
【发布时间】:2016-04-27 09:51:28
【问题描述】:

我刚刚注意到Meteor.call,阻止用户调用集合的插入、更新、删除方法的概念,仍然可以从 JavaScript 控制台调用。

以客户为例:

// client
...

Meteor.call('insertProduct', productInfo);

...

这是服务器部分:

// server
Meteor.methods({
    insertProduct: function( productInfo ){
       Product.insert(...);
    }
})

好的,我知道人们不能直接从他们的 JavaScript 控制台调用 Product.insert()。

但如果他们再多尝试一点,他们会从开发者工具的资源选项卡中发现客户端的 JavaScript 中有 Meteor.call()

所以现在他们可以尝试从控制台调用Meteor.call,然后尝试猜测productInfo 的属性应该是什么。

所以我想知道我们如何才能防止这种最终活动? Meteor.call 是否做得足够好? 还是我遗漏了一些重要的东西?

【问题讨论】:

  • 没有什么,nothing,一个 JavaScript 程序可以做你无法在控制台中复制的事情。 什么都没有。唯一要做的就是在服务器端进行密封验证,这样只有您希望通过的事情才能通过。
  • 另外,如果 Amadan 的评论还不清楚,是的,用户可以从控制台调用 Product.insert()。因此,您需要确保在服务器上设置了正确的允许/拒绝规则(并已删除 insecure 包)。
  • 这没有错。 Web 上的每个应用程序都有某种Meter.call,通常它只是对某个 URL 的 ajax 调用,因此您可以打开控制台并进行 ajax 调用,没关系。只是不要相信客户。

标签: javascript meteor meteor-methods


【解决方案1】:

Meteor.call 是一个全局函数,就像window.alert()。不幸的是,您无法阻止用户调用 Meteor.call。但是,您可以验证数据架构和用户发送的实际数据。我推荐https://github.com/aldeed/meteor-simple-schema(aldeed:simple-schema 作为流星包名称)以确保您不会在项目中获得垃圾数据。

【讨论】:

    【解决方案2】:

    正如其他人指出的那样,“Meteor.call”肯定可以从控制台使用。这里的微妙问题是,可能有一个流星应用程序的合法用户可以反过来在服务器上做坏事。因此,即使在服务器上检查用户是否合法,这本身并不能保证数据受到保护。

    这不仅仅是 Meteor 的问题。我认为所有此类应用都需要潜在地保护其数据免受损坏,即使是通过合法用户

    保护这种损坏的一种方法是使用 IIFE(立即调用函数表达式)

    将您的模块包装在 IIFE 中。在闭包内部保留一个私有变量,该变量存储一个唯一的一次性使用密钥(k1)。该密钥需要使用另一条路线放置在那里 - 可能通过确保在启动时在客户端中触发收集观察者。在这里也可以使用其他策略。这个想法是从服务器中存储 k1 的值并将其存放在一个私有变量中

    然后,每次从代码内部调用 Meteor.call 时,将 k1 作为参数之一传递。服务器依次检查 k1 对于该浏览器连接是否确实合法

    由于 k1 存储在 IIFE 调用的闭包中的私有变量中,因此浏览器控制台上的人很难确定 k1 的值。因此,即使确实可以从浏览器控制台调用“Meteor.call”,也不会造成任何伤害。这种方法应该对数据损坏有很好的威慑作用

    【讨论】:

      【解决方案3】:

      正如@Faysal 所提到的,您有多种方法可以确保您的通话合法。一个简单的步骤是实现alanning:roles 并在您的方法中进行角色检查,如下所示:

      Meteor.methods({
          methodName: function() {
              if (!Roles.userIsInRole(this.userId, 'admin')) {
                  throw new Meteor.Error(403, 'not authorized);
              } else { yourcode });
      

      这样,只有管理员用户可以调用该方法。

      请注意,您还可以从方法中检查this.connection,并确定调用是来自服务器(this.connection === false)还是来自客户端。

      一般来说,从您的方法中进行检查和数据操作是一种不错的方式。允许/拒绝开始时很好,但当您的集合变得越来越重并且您的边缘案例扩大时,就变得非常难以维护。

      【讨论】:

        【解决方案4】:

        您不能从控制台阻止Meteor.call,就像您不能从控制台阻止CollectionName.find().count()。这些是流星中的全局函数。

        但您可以采取一些简单的步骤来保护您的方法。

        1. 使用aldeed:simple-schema 设置您的集合可以接受的数据类型。这将允许您设置集合采用的特定键及其类型(字符串、布尔值、数组、对象、整数)https://github.com/aldeed/meteor-simple-schema
        2. 确保只有登录的用户才能从您的方法更新。或设置全局允许/拒绝规则。 https://www.meteor.com/tutorials/blaze/security-with-methods && https://www.discovermeteor.com/blog/allow-deny-a-security-primer/
        3. 删除包insecureautopublish

        架构和允许/拒绝的简单组合应该可以满足您的需求。

        【讨论】:

          【解决方案5】:

          您现在知道,您不能真正阻止从 Javascript 控制台调用 Meteor.call,我想添加作为 @Stephen 和 @thatgibbyguy 的建议,请务必检查您用户的 role将文档添加到集合中时。 Simple-Schema 将帮助您防止将垃圾数据插入/更新到集合中。和alanning:roles 包通过控制谁有权写入/读取/更新您的收藏文档,无疑使您的应用程序安全。

          Alanning:roles Package

          【讨论】:

            猜你喜欢
            • 2012-11-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-07-03
            • 1970-01-01
            • 2012-02-21
            相关资源
            最近更新 更多