我正在开发一个webapp来教授编程概念。网页上有一些关于编程概念的文本,然后让用户在javascript代码中键入文本编辑器窗口以尝试回答编程问题。当用户点击“提交”时,我会分析他们输入的文本以查看他们是否已解决问题。例如,我要求他们“编写一个名为f
的函数,为其参数添加三个。”
以下是我正在分析用户文本的内容:
eval(usertext);
eval(condition)
。示例条件是"f(1)===4"
。条件来自可靠来源。我的问题:这是否足以防止出现安全问题?我还能做些什么才能成为偏执狂?有没有更好的方法来做我想要的?
如果它是相关的,我的应用程序是在带有Python后端的Google App Engine上,使用JQuery,有个人用户帐户。
答案 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()
是否发生在客户端或服务器端。对于客户端:
我认为可以在配置良好的iframe(https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/)中安全评估
这应该是100%安全的,但是需要几个库并且有一些限制(不支持es6):https://github.com/NeilFraser/JS-Interpreter
有更轻巧的选择,但不是https://github.com/commenthol/safer-eval这样的100%安全的选择。
或者,我认为可以通过将代码手动包装在with语句中来实现类似的功能,从而覆盖this
,全局变量和参数。尽管永远不会100%安全,但在您的情况下还是可行的。
答案 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解释器愿意采取的步骤数。那会很麻烦!