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
通過使用以函數名稱為關鍵字的驗證函數對象值的查找表,可以輕松地避免這種情況。
添加回答
舉報