首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >防火墙安全规则,以防止客户规避使用跟踪

防火墙安全规则,以防止客户规避使用跟踪
EN

Stack Overflow用户
提问于 2014-10-23 03:24:27
回答 2查看 909关注 0票数 1

我们提供的服务,人们将嵌入到他们的网站,我们希望使用Firebase作为我们的后端。我们希望我们的订阅率的网页浏览或类似的基础。现在,我们很难理解如何防止客户缓存客户端js代码,而忽略了试图增加页面视图计数器的任何部分。

我们需要做的是以某种方式创建一个安全规则,该规则原子地阻止某人从一个位置读取数据,除非他们在另一个位置增加了计数器。对怎么做有什么想法吗?

例如,假设以下模式:

代码语言:javascript
复制
{
  "comments" : {
    "-JYlV8KQGkUk18-nnyHk" : {
      "content" : "This is the first comment."
    },
    "-JYlV8KWNlFZHLbOphFO" : {
      "content" : "This is a reply to the first.",
      "replyToCommentId" : "-JYlV8KQGkUk18-nnyHk"
    },
    "-JYlV8KbT63wL9Sb0QvT" : {
      "content" : "This is a reply to the second.",
      "replyToCommentId" : "-JYlV8KWNlFZHLbOphFO"
    },
    "-JYlV8KelTmBr7uRK08y" : {
      "content" : "This is another reply to the first.",
      "replyToCommentId" : "-JYlV8KQGkUk18-nnyHk"
    }
  },
  oldPageViews: 32498,
  pageViews: 32498
}

如果客户端首先增加pageViews字段,那么只允许读取注释的方式是什么?起初,我想要有两个字段(比如pageViews和oldPageViews),从增量pageViews开始,读取注释,然后递增oldPageViews以匹配,并且只允许在pageViews === oldPageViews + 1中读取注释。然而,除非可以原子地完成,否则如果客户端启动进程但没有完成,数据可能会进入损坏状态。

这里是一个试图测试这个想法的代码爱好者。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-25 14:56:56

我建议改变加藤的限速答案:https://stackoverflow.com/a/24841859/75644

数据:

代码语言:javascript
复制
{
  "comments": {
    "-JYlV8KQGkUk18-nnyHk": {
      "content": "This is the first comment."
    },
    "-JYlV8KWNlFZHLbOphFO": {
      "content": "This is a reply to the first.",
      "replyToCommentId": "-JYlV8KQGkUk18-nnyHk"
    },
    "-JYlV8KbT63wL9Sb0QvT": {
      "content": "This is a reply to the second.",
      "replyToCommentId": "-JYlV8KWNlFZHLbOphFO"
    },
    "-JYlV8KelTmBr7uRK08y": {
      "content": "This is another reply to the first.",
      "replyToCommentId": "-JYlV8KQGkUk18-nnyHk"
    },
    "timestamp" : 1413555509137
  },
  "pageViews" : {
    "count" : 345030,
    "lastTs" : 1413555509137
  }
}

安全规则:

代码语言:javascript
复制
{
  "rules": {
    "pageViews": {
      ".validate": "newData.hasChildren(['count','lastTs'])",
      "count": {
        ".validate": "newData.exists() && newData.isNumber() && newData.val() > data.val()"
      },
      "lastTs": {
        // timestamp can't be deleted or I could just recreate it to bypass our throttle
        ".write": "newData.exists()",
          // the new value must be at least 500 milliseconds after the last (no more than one message every five seconds)
          // the new value must be before now (it will be since `now` is when it reaches the server unless I try to cheat)
        ".validate": "newData.isNumber() && newData.val() === now && (!data.exists() || newData.val() > data.val()+500)"
      }
    },
    "comments": {
      // The comments can't be read unless the pageViews lastTs value is within 500 milliseconds of now
      ".read": "root.child('pageViews').child('lastTs').val() > now - 501",
      ".write": true
    }
  }
}

注意:我还没有测试过这个,所以您需要使用它来看看它是否有效。

另外,根据您的示例数据,我没有处理uid的数据,您需要确保您正在管理谁可以在这里读写。

票数 3
EN

Stack Overflow用户

发布于 2014-10-27 20:06:09

Justin对节流代码的适应似乎是一个很好的起点。还有一些令人讨厌的漏洞,比如强制更新计数器,从计数器中获取可量化的度量/分析(这需要通过某种方式连接到一个统计工具,并且对于准确的账单报告和客户查询也是必要的),并且能够准确地确定访问何时“结束”。

根据Justin最初的想法,我认为通过简化客户所负责的金额,可以省去大量的开销。也许是这样:

  1. 仅强制用户更新时间戳计数器。
  2. 使用node.js脚本监视计数器的更新
  3. 让node.js脚本“存储”审计数据,最好将其发送到keen.io、intercom.io等分析工具。

从这个基础开始,我将调整安全规则和结构如下:

代码语言:javascript
复制
{
  "rules": {
    "count": {
      // updated only from node.js script
      // assumes our node worker authenticates with a special uid we created 
      // http://jsfiddle.net/firebase/XDXu5/embedded/result/
      ".write": "auth.uid === 'ADMIN_WORKER'", 
      ".validate": "newData.exists() && newData.isNumber() && newData.val() > data.val()"
    },
    "lastTs": {
      // timestamp can't be deleted or I could just recreate it to bypass our throttle
      ".write": "newData.exists()",
        // the new value must be equal to now (i.e. Firebase.ServerValue.TIMESTAMP)
      ".validate": "newData.isNumber() && newData.val() === now"
    },
    "comments": {
      // The comments can't be read unless the pageViews lastTs value is within 30 seconds
      ".read": "root.child('pageViews').child('lastTs').val() > now - 30000",
      "$comment": {
        ".write": "???"     
      }
    }
  }
}

现在,我将编写一个简单的节点脚本来执行计数和管理任务:

代码语言:javascript
复制
var Firebase = require('firebase');
var ref = new Firebase(URL);
ref.child('lastTs').on('value', heartbeatReceived);
var lastCheck = null;

function heartbeatReceived(snap) {
  if( isNewSession(snap.val()) ) {
    incrementCounter();
  }
  updateStatsEngine(snap);
}

function incrementCounter() {
  ref.child('count').transaction(function(currVal) {
    return (currVal||0) + 1;
  });
}

function isNewSession(timestamp) {
  // the criteria here is pretty arbitrary and up to you, maybe
  // something like < 30 minutes since last update or the same day?
  var res = lastCheck === null || timestamp - lastCheck > 30 * 60 * 1000;
  lastCheck = timestamp;
  return res;
}

function updateStatsEngine(snap) {
  // contact keen.io via their REST API
  // tell intercom.io that we have an event
  // do whatever is desired to store quantifiable stats
  // and track billing info
  //
  //var client = require('keen.io').configure({
  //    projectId: "<project_id>",
  //    writeKey: "<write_key>",
  //    readKey: "<read_key>",
  //    masterKey: "<master_key>"
  //});
  //
  //client.addEvent("collection", {/* data */});
}

这种方法的缺点是,如果我的管理脚本出现故障,那么这段时间内的任何事件都不会被记录。然而,这个脚本的美妙之处在于它的简单。

它不会有太多的bug。添加monit、upstart或其他工具,以确保它不会崩溃。工作完成了。

它也有很高的用途。我可以在我的笔记本电脑,甚至我的Android手机(作为HTML页面)在紧要关头运行它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26520793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档