1

我开始构建/设计一个新的单页 Web 应用程序,并且真的想主要使用客户端技术(HTML、CSS、JavaScript/CoffeScript)作为前端,同时拥有一个瘦 REST API 后端来提供数据到前端。出现的一个问题是关于 JavaScript 的安全性。例如,某些链接和 UI 元素将仅根据用户附加的角色和资源显示。当用户登录时,它将进行一个 REST 调用来验证凭据,然后返回一个 json 对象,该对象具有该用户的所有权限,该对象将存储在一个 JavaScript 对象中。

让我们来看看这段 javascript:

// Generated by CoffeeScript 1.3.3
(function() {
  var acl, permissions, root;

  root = typeof exports !== "undefined" && exports !== null ? exports : this;

  permissions = {
    //data…
  };

  acl = {
    hasPermission: function(resource, permission, instanceId) {
      //code….
    }
  };

  root.acl = acl;

}).call(this);

现在这个代码设置确保即使通过控制台,也没有人可以修改变量权限。这里的问题是,由于这是一个单页应用程序,我可能想要更新权限而不必刷新页面(也许他们添加了一条记录,然后需要将其添加到他们的权限中)。我能想到的唯一方法是添加类似

setPermission: function(resource, permission, instanceId){
  //code…
}

到 acl 对象,但是如果我这样做,这意味着浏览器控制台中的某个人也可以使用它来为自己添加他们不应该拥有的权限。有没有办法添加无法从浏览器控制台访问但可以从 JavaScript 文件中的代码访问的代码?

现在即使我可以防止上述问题,我仍然有一个更大的问题。无论我需要什么拥有 hasPermission 功能,但是当它以这种方式声明时,我可以在浏览器控制台中通过执行以下操作覆盖该方法:

acl.hasPermission(resource, permission, instanceId){return true;}

现在我可以看到一切了。无论如何定义此方法是用户无法覆盖它的方式(例如将其标记为最终或其他东西)?

需要注意的是,每个 REST API 调用也会检查权限,所以即使他们看到了他们不应该看到的东西,他们仍然无法做任何事情,并且 REST API 会因为权限问题而后悔请求. 有人建议在服务器端生成模板,但我真的不喜欢这个想法,因为它在前端和后端技术堆栈之间创建了非常强的耦合。例如,如果出于某种原因我们需要将 PHP 迁移到 Python 或 Ruby,如果模板是在客户端用 JavaScript 构建的,我只需要重新构建 REST API,所有前端代码都可以保留相同,但如果我在服务器端生成模板,情况并非如此。

4

3 回答 3

4

无论您做什么:您还必须检查服务器端的所有权限(如您所述,在您的 REST 后端)。无论您跳过什么障碍,有人将能够进行他们不应该进行的 REST 调用。

这有效地使您的客户端安全系统成为优化:您尝试仅向用户显示允许的操作,并尝试避免往返服务器以获取允许的操作。

因此,您实际上并不需要关心用户是否可以“破解”它:如果他们破坏了您的应用程序,他们可以保留这两个部分。不会发生任何错误,因为服务器不会让他们执行未经授权的操作。

但是,我仍然会以期望“访问被拒绝”作为有效答案的方式编写客户端代码(并且不需要异常)。出现这种响应的原因有很多:如果登录用户在打开浏览器时更改了权限,那么客户端的安全描述不再与服务器匹配,应该优雅地处理这种情况(显示“抱歉,不允许此操作”并重新加载安全描述,例如)。

于 2012-09-05T13:13:23.137 回答
2

永远不要相信 Javascript 代码或一般的前端。人们甚至可以在代码到达您的浏览器(嗅探器等)之前对其进行修改,并且无论如何大多数变量都是可访问和可修改的……相信我:您在前端永远不会安全:)

始终在服务器端检查凭据,而不仅仅是在前端!

于 2012-09-05T13:14:50.487 回答
0

在现代浏览器中,您可以使用Object.freezeorObject.defineProperty来确保该hasPermission方法不能被重新定义。

我还不知道如何克服这个问题setPermission。也许最好只依赖那里的服务器端安全性,正如你所说的那样,无论如何你都有。

于 2012-09-05T13:39:15.110 回答