2 回答
TA贡献1834条经验 获得超8个赞
所以问题是:从数组中过滤掉任何不需要的字符串(名称)是否足够安全以对抗 eval 的可利用性?
不,这不安全。事实上,它基本上没有采取任何措施来保护您,因为您允许的 cookie 名称仍然完全不受保护和消毒。您拥有的内容可能不安全,因为恶意客户端可以在该 cookie 中放入他们想要的任何内容,而您“希望”他们找不到超出您拥有的字符串分隔符的内容。但是,可以通过终止字符串然后添加函数调用来打破该字符串分隔符。这可能允许攻击者在您的服务器上执行任意代码。
您唯一应该使用eval()的是来自您自己的服务器端代码的可信字符串或来自外部的完全净化的字符串。但是,几乎总是,您不需要,eval()因为还有另一种更安全的编码方式。
eval()在这里,您根本不需要使用。您可以为要调用的合法函数创建一个查找表,然后将函数直接传递给它:
try {
res.locals[cookie] = validateCookie[cookie](req.cookies[cookie]);
} catch(e) {
// either invalid cookie or exception in the function
// handle that here
}
当然,您的validateCookie[cookie]()函数还必须进行防御性编码,才能知道它可能会传递任何内容。您没有向我们展示该函数的代码以便能够对其进行进一步评论。
在本例中,validateCookie是一个查找表,其中包含有效cookie名称及其相应的函数:
// cookie processing lookup table
const validateCookie = {
cookieName1: validateCookieName1,
cookieName2: validateCookieName2
};
像这样的查找表通常是您避免尝试创建函数名称和字符串并用于eval()调用它的方法。这还增加了安全功能,即此代码无法调用查找表中不存在的任何函数。
TA贡献1788条经验 获得超4个赞
不,代码不安全,不是因为它没有清理验证方法的名称,而是因为它在扩展字符串模板文字时将上传的文本评估为 JavaScript:
`... ${req.cookies[cookie]} ...`
我刚刚使用精心设计的字符串值测试并注入了代码req.cookies[cookie]
,我不会在此处发布该值。
在不扩展数据字符串的情况下评估验证调用可能会稍微安全一些,如下所示
`validateCookie${cookie}` + "(req.cookies[cookie])"
这会将上传的文本传递到验证例程,而无需将其作为代码进行评估,但完全避免的安全性eval
保持不变。eval
通过使用以函数名称为关键字的验证函数对象值的查找表,可以轻松地避免这种情况。
添加回答
举报