JavaScript代码中的安全性

Security in JavaScript Code

本文关键字:安全性 代码 JavaScript      更新时间:2023-09-26

我开始构建/设计一个新的单页web应用程序,我真的想主要将客户端技术(HTML、CSS、JavaScript/CoffeeScript)用于前端,同时拥有一个精简的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…
}

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

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

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

现在我可以看到一切了。是否有任何方法可以定义为这样一种方式,即用户不能覆盖它(比如将其标记为final或其他什么)?

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

无论您做什么:都必须检查服务器端的所有权限(如您所述,在REST后端)。无论你经历了什么困难,都有人能够做出他们不应该做出的REST调用。

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

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

然而,我仍然会以一种期望"访问被拒绝"作为有效答案(不一定是异常)的方式编写客户端代码。出现这种响应的原因有很多:如果登录用户的权限在打开浏览器时发生了更改,则客户端的安全说明与服务器不再匹配,这种情况应该得到妥善处理(例如,显示"对不起,不允许执行此操作"并重新加载安全说明)。

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

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

在现代浏览器中,可以使用Object.freezeObject.defineProperty来确保hasPermission方法无法重新定义。

我还不知道如何克服setPermission的问题。也许最好只依赖服务器端的安全性,正如您所说的那样。