2 回答

TA貢獻(xiàn)1815條經(jīng)驗 獲得超13個贊
我主要擔(dān)心的是原型污染
注意JSON.parse
不會污染任何原型對象。如果 JSON 字符串有一個"__proto__"
鍵,那么該鍵將像任何其他鍵一樣被創(chuàng)建,無論該 JSON 中對應(yīng)的值是什么,它最終都會作為該屬性值,而不是在原型對象 () 中Object.prototype
。
風(fēng)險在于您之后對該對象所做的操作。如果您執(zhí)行(深)復(fù)制,使用屬性分配 或Object.assign
,那么您可能會改變原型對象。
我們?nèi)绾卧谶\行前對其進(jìn)行消毒
JSON.parse(untrustedString)
?...我認(rèn)為可以通過正則表達(dá)式處理
不要為此使用正則表達(dá)式。使用 的第二個參數(shù)JSON.parse
:
const cleaner = (key, value) => key === "__proto__" ? undefined : value;
// demo
let json = '{"user":{"__proto__":{"admin": true}}}';
console.log(JSON.parse(json));
console.log(JSON.parse(json, cleaner));

TA貢獻(xiàn)1794條經(jīng)驗 獲得超7個贊
在你對它做任何事情之前,userString
它只是一個字符串,并且該字符串中的任何內(nèi)容本身都不會損害系統(tǒng),除非系統(tǒng)做一些事情來允許這種損害,比如以不安全的方式處理它。
輸入JSON.parse()
。
JSON.parse()
只是一個格式轉(zhuǎn)換工具。它不會從數(shù)據(jù)中運行任何方法(原型污染利用依賴于它),或者實際上什至查看包含在字符串化對象本身中的數(shù)據(jù),除了它包含的結(jié)構(gòu)語法和 JavaScript 保留字,用于驗證目的(MDN polyfill例子)。與字符串相同的原則適用于此;如果您不對輸出對象做任何不安全的事情,它就不會傷害您或您的系統(tǒng)。
歸根結(jié)底,防止濫用歸結(jié)為驗證和安全數(shù)據(jù)處理實踐:
檢查解析字符串產(chǎn)生的對象,并在嚴(yán)格的參數(shù)范圍內(nèi)驗證它,忽略原型突變。
使用
Object.prototype.hasOwnProperty.call()
。使用 eslint(no-prototype-builtins 規(guī)則)等工具在您的代碼庫中強(qiáng)制實施這些做法。不要指望用戶發(fā)送完美、安全的數(shù)據(jù)。
在您鏈接的文章中,作者提到了這個確切的想法:
...來自用戶的數(shù)據(jù)應(yīng)始終進(jìn)行過濾和清理。
添加回答
舉報