【问题标题】:Limit what javascript a user can input限制用户可以输入的 javascript
【发布时间】:2015-12-18 03:59:35
【问题描述】:

我希望允许用户将他们自己的数学公式输入到我可以通过 javascript 运行的字段中,但我只希望他们输入与数学相关的代码并让他们只能访问 Math 对象。

所以我只希望用户能够输入数学符号(+、-、*、% 等)并使用 Math 对象中的任何函数。

我最初考虑在客户端和服务器上使用正则表达式来验证他们只输入了我允许的内容,并且由于他们无法在该代码进入服务器之前运行该代码,我想也许可以,但我仍然不知道是否只是正则表达式本身甚至可以为此工作。

我怎样才能安全地允许和信任这样的用户输入?

编辑:公式将始终在客户端上运行,但我会将它们作为字符串存储在数据库中,以便在他们想要运行时发送给他们。

【问题讨论】:

  • 服务器上只有一个地方可以安全地验证用户输入。
  • 好吧,如果应用程序在客户端,而服务器只是为应用程序提供服务,那么我不明白为什么他不能在客户端验证。
  • 您将需要使用 DSL 和解析器来允许用户使用数学函数。可能会涉及到正则表达式,但从头开始构建 DSL 对于单个 Stack Overflow 问题来说过于宽泛。
  • 是的,我知道,这就是为什么我不会让代码在进入服务器之前运行,但我不确定如何去除除数学对象和符号之外的所有内容
  • 如果您计划在您的服务器上运行用户提交的代码,这是一个严重而复杂的安全问题。 (JavaScript 正在朝着使这一切变得更加实用的方向迈出一小步,但它还有很长的路要走。)任意 JavaScript 代码可以通过一系列特殊字符运行,例如 []()~!^几乎没有字母——创建一个安全的验证方法比听起来要复杂得多。正如其他人所建议的那样,您最好创建一个简单的解析器并自己评估表达式,而不是将它们评估为 JS。

标签: javascript angularjs node.js mean-stack


【解决方案1】:

因此,许多 cmets 引导我找到 MathJs,并且通过阅读该站点上的一些文档和 cmets,我发现允许用户输入并允许 Math 对象是安全的。

将它与workerpool 结合起来以限制执行时间,我认为这应该有我需要的一切。

感谢那些帮助我指明正确方向的人!

【讨论】:

    【解决方案2】:

    如果您可以保证文本不会在服务器上执行,那么从概念上讲,您可以尝试下面的evalFormula

    <html>
      <head>
        <script type="text/javascript">
    
        function evalFormula(str) {
    
          // shielding 
          var window = null;  
          var document = null;
    
          // shortcuts
          var abs = Math.abs;
    
          return eval(str); 
        }
    
        console.log( evalFormula("abs(-42)") );    
        console.log( evalFormula("document.write('')") ); // throws error
    
        </script>
      </head>
    <body>
    </body>
    </html>
    

    请注意,该函数包含// shielding 部分,该部分应包含公式上下文中应禁止的所有“危险”对象的“上限”。 注意:该集合很难完整定义,但原则上是可能的。

    函数的局部作用域可能包含数学函数的快捷方式,因此它们可以用作abs(-42),但不能用作Math.abs(-42)

    上面代码的想法:在 JS 中 eval() 在当前函数的上下文中执行。因此,它的所有局部变量都可用于正在评估的文本。

    【讨论】:

    • 嗯,这很聪明。从没想过要创建新窗口和文档变量。我确实看到了如何定义你所做的和不想要的一切变得非常困难。但是,您的回答确实使我找到了 MathJs,并且从该站点上的初始阅读开始,使用该库来评估包含 Math 对象的公式是安全的。
    • [].constructor.constructor('return document')().write('oh no');
    • @JeremyBanks 我知道而且还有更多。如果一个人可以编写函数供他人使用,那将是危险的。但是,如果您的应用只是供个人使用的“智能计算器”,那么这样的屏蔽可以防止 意外 输入诸如 location.href = "other.htm" 之类的内容,而不是更多。
    猜你喜欢
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多