这样用`with`语句使用`eval`是否安全?

时间:2019-04-08 17:29:46

标签: javascript

模板实际上来自同一目录中的index.html文件。 上下文可以包含用户输入。

const context = { id: 1 };
const template = '<html><body>${id}</body></html>';
with (context) {
  return eval(`\`${template}\``);
}

我了解XSS保护。

我正在寻找有关如何打破此解决方案的示例,用户输入有什么方法可以运行后端代码?

2 个答案:

答案 0 :(得分:1)

取决于如何为context提供值,可以设置context.template。这将更改变量标识符template以引用属性context.template,并将该属性的值传递给eval

因此,您可以通过类似{p>的context属性来执行服务器端代码

template: "${alert(1)}"

或者,如果可以为context属性赋予函数值,则设置context.eval将允许立即执行该函数。 (但是,这不太可行,因为用户输入更有可能被普遍视为字符串。)

您可以通过在进入delete context.template; delete context.eval;块之前执行with来避免这两个问题。

答案 1 :(得分:0)

使用eval永远不是一个好主意。

如果要插入字符串,可以使用template literals

即使那样,您也应该清理使用输入以避免XSS。清理字符串的一种简单方法是将输入读取为文本,这样可以使输入转义,然后将内容转储到模板占位符中。

const context = { id: 1 };
const template = `<html><body>${getHTMLSafeText(context.id)}</body></html>`;

function getHTMLSafeText(content) {
    let div = document.createElement('div');

    div.textContent = content;

    return div.innerHTML;
}