如何安全地“评估”网页中的用户代码?

时间:2011-07-15 23:08:50

标签: javascript security eval jslint

我正在开发一个webapp来教授编程概念。网页上有一些关于编程概念的文本,然后让用户在javascript代码中键入文本编辑器窗口以尝试回答编程问题。当用户点击“提交”时,我会分析他们输入的文本以查看他们是否已解决问题。例如,我要求他们“编写一个名为f的函数,为其参数添加三个。”

以下是我正在分析用户文本的内容:

  1. 使用严格设置对文本运行JSLint,特别是不使用浏览器或控制台功能。
  2. 如果有任何错误,请显示错误并停止。
  3. eval(usertext);
  4. 循环传递作业的条件eval(condition)。示例条件是"f(1)===4"。条件来自可靠来源。
  5. 显示通过/失败的条件。
  6. 我的问题:这是否足以防止出现安全问题?我还能做些什么才能成为偏执狂?有没有更好的方法来做我想要的?

    如果它是相关的,我的应用程序是在带有Python后端的Google App Engine上,使用JQuery,有个人用户帐户。

5 个答案:

答案 0 :(得分:11)

因此,如果您仅为他们评估用户的输入,我可以判断,这不是安全问题。只有当他们的输入被其他用户评估时,您才会遇到问题。

评估用户的输入并不比查看源,查看HTTP标头,使用Firebug检查JavaScript对象等更糟糕。他们已经可以访问所有内容。

如果您确实需要保护其代码,请查看Google Caja http://code.google.com/p/google-caja/

答案 1 :(得分:2)

这是一个棘手的问题。您的网站上没有eval()用户代码的安全方式。

答案 2 :(得分:1)

无法做到。浏览器不为网页提供API,以限制在给定上下文中可以执行的代码类型。

但是,这可能无关紧要。如果您不在网站上使用任何cookie,那么执行任意Javascript可能不是问题。毕竟,如果没有身份验证的概念,那么伪造请求就没有问题。此外,如果您可以确认用户意味着执行他/她发送的脚本,那么您也应该受到保护,免受攻击者的侵害,例如,如果您只运行键入页面的脚本而不是脚本通过GET或POST数据提交,或者如果您包含某些类型的唯一令牌以确认请求来自您的网站。

然而,核心问题的答案是,它几乎无法完成,并且用户输入永远不可信任。对不起:/

答案 3 :(得分:0)

不清楚eval()是否发生在客户端或服务器端。对于客户端:

答案 4 :(得分:0)

您最大的问题将始终是防止在用户提供的代码中发生无限循环。您可以通过在正确的上下文中运行eval来隐藏“私人”引用,例如:

let userInput = getUserInput();
setTimeout(() => {
  let window = null;
  let global = null;
  let this = null;
  // ... set any additional references to `null`
  
  eval(userInput);
}, 0);

您可以将以上代码包装在try/catch中,以防止语法和逻辑错误崩溃到受控eval范围之外,但是(provably)永远无法检测传入的用户输入是否定义了一个无限循环,该无限循环将占用javascript的单线程,从而使其运行时上下文完全停止。此类问题的唯一解决方案是定义自己的javascript解释器,使用它来处理用户的输入,并提供一种机制来限制javascript解释器愿意采取的步骤数。那会很麻烦!