这可能是一个特定的问题(研究项目),但我正在寻找一种好方法,使这个程序比现在更"安全".
目标是接受任意用户代码(在通过单元测试和手动判断之后),并将其合并到正在运行的程序中,而无需重新加载应用程序.
具体的例子是,它是一个持续执行的绘图应用程序,我希望学生/其他用户能够提交脚本(遵循特定的格式/指导原则).
我目前的实现是要求用户指定他们的类名与他们的文件名匹配(例如,myclass.js
中有一个const myclass = class { ... }
块).然后,当我看到我的服务器中存在一个新文件时(一个判断特定目录内容的FlaskTM应用程序),该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)