下面的JavaScript安全的从任意代码执行?

我正在贡献一个JavaScript框架,具有相当于下面的代码:

eval("'" + user_input.replace(/'/g, "'") + "'"); 

我知道这很糟糕 – 不需要说服我。 我想知道的是,我可以在这里注入任意代码吗?

乍一看, user_input.replace("'", "'")会阻止我跳出string。 不过,我可以通过新行,如\nalert(123)\n ,但结果总是一个语法错误,例如

 ' alert(123) ' 

实际上是否有一个用于代码注入的向量,除了导致语法错误?

虽然这无疑是一个令人担忧的模式,但如果完全按照所述方式使用,则是安全的。 唯一可以在Javascript中终止单引号字符的字符是单引号字符。 只要该字符不会出现在插入单引号的string中,就不可能将其解释为string以外的任何字符。

关于最糟糕的事情,我能想到的,你可以做的是结束一个反斜杠的string,这将导致一个未终止的string,例如,如果user_input是:

 example\ 

那么评估的代码将是

 'example\' 

这会导致语法错误,因为包含在eval的string永远不会终止。 但是,如果真正的eval实际上更复杂, 这是可以利用的 。 例如,如果代码是:

 var escaped_input = user_input.replace(/'/g, "&39;"); eval("'" + escaped_input + "' some more stuff '" + escaped_input + "'"); 

那么它可以被利用一个像这样的input:

 ; alert(1); // \ 

这将导致:

 '; alert(1); // \' some more stuff '; alert(1); // \' ^^^^^^^^^ 

其中下划线的内容将被评估,因为应该退出string的报价已经逃脱,将下一个单引号转换为结束报价! 为了安全起见,如果可能的话,我build议转义或更换反斜杠(除非你明确地尝试使用eval()来处理它们,在这种情况下,你可能会捕获exception)。