正如这里所解释的,为了避免使用evil方法,我使用了函数构造函数。没有找到更好的注入上下文的方法:
function evalContext(context: Record<string, unknown>) {
const injectContext = Object.keys(context).reduce(
(acc, key) => `${acc}${key}=context.${key};`,
'',
);
return Function(`context`, `${injectContext}${script}`)(context);
}
const handleKeyDown: KeyboardEventHandler<HTMLTextAreaElement> = useEventCallback((event) => {
if (event.code === 'KeyE' && event.metaKey) {
evalContext({ a: 3, b: 4, log: console.log });
event.preventDefault();
event.stopPropagation();
}
});

尽管如此,它还是有效的(不需要用this作为键的前缀)。主要问题是是否有可能“隐藏”浏览器对象(窗口、文档、位置、.)。从安全性角度看,函数构造函数中使用的脚本只对帐户所有者可见。希望这是安全的。
作为一个附带的问题,试着使用一些代码编辑器库:摩纳哥编辑器,react简单代码编辑器,@uiw/ few textarea code编辑器,@patternfly/few code-编辑器.还没有成功地运行它们中的任何一个(在next.js上下文中破坏了这一点,破坏了它)。请您推荐其中任何一个在NJS上的最新版本中工作得很好吗?
更新:
基于@kelly的建议:
function evalContext(context: Record<string, unknown>) {
const injectContext = Object.keys(context).reduce(
(acc, key) => `${acc}${key}=context.${key};`,
'',
);
return Function(
'context',
'window',
'document',
'location',
'localStorage',
'navigation',
'fetch',
'frames',
'history',
`(function () {${injectContext}${script}}).call({})`,
)(context);
}

发布于 2022-09-07 20:56:05
我想您可以通过添加参数来“覆盖”全局名称:
return Function(`context`, `window`, `globalThis`, `document`, ..., `${injectContext}${script}`)(context, undefined, undefined, undefined, ...);类似于此示例:
function overridden(window) {
window.open("site");
}
overridden(undefined); // error will occur由于不提供参数基本上与提供undefined相同,所以可以完全省略undefined:
return Function(`context`, `window`, `globalThis`, `document`, ..., `${injectContext}${script}`)(context);请记住,全局命名空间中有很多东西。
Object.keys(window)会给你一个主意..。
https://stackoverflow.com/questions/73641040
复制相似问题