Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法在Javascript中坐牢,这样DOM就不会';看不见_Javascript_Dom_Scripting_Restriction - Fatal编程技术网

有没有办法在Javascript中坐牢,这样DOM就不会';看不见

有没有办法在Javascript中坐牢,这样DOM就不会';看不见,javascript,dom,scripting,restriction,Javascript,Dom,Scripting,Restriction,我真的很想为用户提供一些脚本功能,同时不让它访问更强大的功能,比如修改DOM。也就是说,所有输入/输出都通过给定接口进行隧道传输。就像一种受限JavaCScript 例如: 如果接口是检查应答(func) 这是允许的: checkanswer( function (x,y)={ return x+y; } 但这些是不允许的: 警报(1) document.write(“你好世界”) eval(“警报()”) 编辑:我想到的是一种使用javascript实现的简单语言,类似于听起来你需要

我真的很想为用户提供一些脚本功能,同时不让它访问更强大的功能,比如修改DOM。也就是说,所有输入/输出都通过给定接口进行隧道传输。就像一种受限JavaCScript

例如: 如果接口是
检查应答(func)
这是允许的:

checkanswer( function (x,y)={
   return x+y;
}
但这些是不允许的:
警报(1)

document.write(“你好世界”)

eval(“警报()”)


编辑:我想到的是一种使用javascript实现的简单语言,类似于

听起来你需要处理用户输入的数据,并根据允许内容的白名单或黑名单替换无效标记。

T.J.Crowder对“军备竞赛”提出了极好的观点建造一个水密沙箱将是非常困难的

不过,可以很容易地重写某些函数

简单功能:

根据我们的研究,甚至覆盖像
document.write
这样的东西也很简单

document.write = function(str) {}
如果这在您需要支持的浏览器中有效(我假设它在所有浏览器中都有效),那么这可能是最好的解决方案

备选方案:

  • 将脚本沙箱化到不同子域上的IFrame中。可以操纵自己的DOM并发出alert()等,但周围的站点将保持不变。无论您选择哪种方法,您可能都必须这样做

  • 使用允许函数的白名单解析用户代码。这样做也非常复杂,因为有太多的符号和变体需要处理

  • 有几种方法可以监视DOM的更改,我很确定可以构建一种机制立即恢复任何更改,这与Windows的DLL管理非常类似。但这将是非常复杂的建设和非常资源密集

    • Edit这个答案与您的编辑前问题有关。我不知道有任何使用Javascript实现的脚本语言,尽管我希望有一些。例如,有人曾为Javascript编写过BASIC(以前有一个链接,但它已经腐烂)。因此,这个答案的其余部分是相当学术性的,但我把它留作讨论、说明,甚至是警告之用。此外,我绝对同意-不要自己这样做,使用其他人的作品,例如。)

      如果您允许在用户生成的内容中使用任何脚本,请准备好迎接这样一个事实:您将进入一场军备竞赛,人们将在您的保护机制中发现漏洞并加以利用,您将对这些漏洞做出响应。我想我可能会避开它,但你知道你的社区和你处理虐待的选择。因此,如果你对此做好准备:

      由于Javascript进行符号解析的方式,似乎可以在
      窗口
      文档
      ActiveXObject
      XMLHttpRequest
      、以及类似内容没有其通常含义的上下文中评估脚本:

      // Define the scoper
      var Scoper = (function() {
          var rv = {};
      
          rv.scope = function(codeString) {
              var window,
                  document,
                  ActiveXObject,
                  XMLHttpRequest,
                  alert,
                  setTimeout,
                  setInterval,
                  clearTimeout,
                  clearInterval,
                  Function,
                  arguments;
                  // etc., etc., etc.
      
              // Just declaring `arguments` doesn't work (which makes
              // sense, actually), but overwriting it does
              arguments = undefined;
      
              // Execute the code; still probably pretty unsafe!
              eval(codeString);
          };
      
          return rv;;
      })();
      
      // Usage:
      Scoper.scope(codeString);
      
      (现在它使用了邪恶的
      eval
      ,但我无法立即想出一种方法,在不使用
      eval
      的情况下,在浏览器中隐藏默认对象,并且如果您仍然以文本形式接收代码……)

      但它不起作用,它只是部分解决方案(详见下文)。其中的逻辑是,在
      代码字符串
      中的代码中,任何试图访问
      窗口
      (例如)的尝试都将访问局部变量
      窗口
      ,而不是全局变量;其他的也一样。不幸的是,由于符号的解析方式,可以使用或不使用
      窗口访问
      窗口的任何属性。
      前缀(
      警报,例如),因此您也必须列出这些属性。这可能是一个很长的列表,不仅仅是因为如前所述,IE会将任何带有名称或ID的DOM元素转储到
      窗口中。因此,您可能必须将所有这些都放在它自己的iframe中,这样您就可以围绕这个问题进行结束运行,“只”需要处理标准的东西。还要注意我是如何将
      范围
      函数作为对象的属性的,然后您只通过属性调用它。这使得
      this
      被设置为
      Scoper
      实例(否则,在原始函数调用中,
      this
      默认为
      window
      !)

      但是,正如博宾斯所指出的,有很多不同的方法可以达到目的。例如,
      codeString
      中的这段代码成功地打破了上面的牢笼:

      (new ('hello'.constructor.constructor)('alert("hello from global");'))()
      
      现在,也许你可以更新监狱,使特定的漏洞不起作用(在所有内置对象上乱搞
      构造函数
      属性),但我倾向于怀疑它。如果可以的话,有人(比如Bob)会想出一个新的漏洞,比如:

      (function(){return this;})().alert("hello again from global!");
      
      因此出现了“军备竞赛”


      要做到这一点,唯一真正彻底的方法是在站点中构建一个合适的Javascript解析器,解析它们的代码并检查非法访问,然后让代码运行。这是一个很大的工作,但是如果你的用例证明了这一点…

      你可以像Facebook那样做。他们正在对所有javascript源代码进行预处理,为除自己的包装器API之外的所有名称添加前缀。

      不太可能。JavaScript是一种非常动态的语言,具有许多隐藏的或特定于浏览器的特性,可以用来摆脱任何你可以设计的牢狱之灾


      不要把这件事归咎于你自己。考虑使用现有的“迷你JS语言”项目,例如.

      ,我得到另一种方法:使用谷歌GoelsWorksPoPAPI BR> 看到这个了吗

      已创建的辅助进程没有访问权限 到DOM;对象,如文档和 窗口仅存在于主页面上。 这是工人的后果
      function safe(code,args)
      {
          if (!args)
              args=[];
          return (function(){
          for (i in window) 
              eval("var "+i+";");
          return function(){return eval(code);}.apply(0,args);
          })();
      }
      
      
      
      ff=function()
      {
          return 3.14;
      }
      
      console.log(safe("this;"));//Number
      console.log(safe("window;"));//undefined
      console.log(safe("console;"));//undefined
      console.log(safe("Math;"));//MathConstructor
      console.log(safe("JSON;"));//JSON
      console.log(safe("Element;"));//undefined
      console.log(safe("document;"));//undefined
      console.log(safe("Math.cos(arguments[0]);",[3.14]));//-0.9999987317275395
      console.log(safe("arguments[0]();",[ff]));//3.14
      
      Number
      undefined
      undefined
      MathConstructor
      JSON
      undefined
      undefined
      -0.9999987317275395
      3.14