这可能是一个特定的问题(研究项目),但我正在寻找一个好方法,使这个程序显着“安全”比它目前。
目标是接受任意用户代码(在它通过单元测试和手动检查之后),并将其合并到正在运行的程序中,而无需重新加载应用程序。
具体的例子是,它是一个连续执行的绘图应用程序,我希望学生/其他用户能够提交脚本(遵循特定的格式/指南)。
我目前的实现是要求用户指定他们的类名与他们的文件名相匹配(例如,myclass.js
内部有一个const myclass = class { ... }
块)。然后,当我看到服务器(一个检查特定目录内容的Flask应用程序)中存在一个新文件时,JavaScript应用程序将加载该特定文件。
目前,我有一个promise
来确保脚本被加载,但我所做的一般方法是将它带入内存:
function loadNewScript(scriptName) {
let s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("src", `/static/techniques/${scriptName}`);
let nodes = document.getElementsByTagName("*");
let node = nodes[nodes.length - 1].parentNode;
node.appendChild(s);
}
然而,我预期的安全问题(除了我假设的任意代码)是我目前正在使用eval
将类带入内存:
// technique comes in as 'myclass.js'
function loadObject(technique) {
try {
let obj = eval(technique.split(".")[0]);
let _activeObj = new obj();
if (typeof _activeObj != "undefined") {
return _activeObj;
}
return null;
}
catch (e) { // will check for syntax errors, but this usually trips when the script isn't loaded yet
return null;
}
}
目前这是可行的,但是我有点担心这里使用的eval
。我看过关于使用window
或this
命名空间的帖子,但据我所知,您不能将动态加载的脚本添加到全局命名空间中?无论如何,使用window['myclass']
或this['myclass']
在加载后无法工作。(How to execute a JavaScript function when I have its name as a string)
1条答案
按热度按时间8ehkhllq1#
实际上,如果您已经将“任意”(已审查)代码加载到动态
<script>
中,那么为了安全性而避免eval
是没有意义的。window['myclass']
不工作的问题是因为const
does declare a global variable but create a property of the global object。您需要更改脚本以使用var myclass = class { ... };
。但是,我建议您更改您的实现,以要求遵循ES6模块格式的文件:
然后你可以用
如果你需要
loadObject
方法是同步的(而不是返回一个promise),你可以use an object orMap
as a class registry: