2 回答

TA貢獻1815條經驗 獲得超13個贊
我主要擔心的是原型污染
注意JSON.parse
不會污染任何原型對象。如果 JSON 字符串有一個"__proto__"
鍵,那么該鍵將像任何其他鍵一樣被創建,無論該 JSON 中對應的值是什么,它最終都會作為該屬性值,而不是在原型對象 () 中Object.prototype
。
風險在于您之后對該對象所做的操作。如果您執行(深)復制,使用屬性分配 或Object.assign
,那么您可能會改變原型對象。
我們如何在運行前對其進行消毒
JSON.parse(untrustedString)
?...我認為可以通過正則表達式處理
不要為此使用正則表達式。使用 的第二個參數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貢獻1794條經驗 獲得超7個贊
在你對它做任何事情之前,userString
它只是一個字符串,并且該字符串中的任何內容本身都不會損害系統,除非系統做一些事情來允許這種損害,比如以不安全的方式處理它。
輸入JSON.parse()
。
JSON.parse()
只是一個格式轉換工具。它不會從數據中運行任何方法(原型污染利用依賴于它),或者實際上什至查看包含在字符串化對象本身中的數據,除了它包含的結構語法和 JavaScript 保留字,用于驗證目的(MDN polyfill例子)。與字符串相同的原則適用于此;如果您不對輸出對象做任何不安全的事情,它就不會傷害您或您的系統。
歸根結底,防止濫用歸結為驗證和安全數據處理實踐:
檢查解析字符串產生的對象,并在嚴格的參數范圍內驗證它,忽略原型突變。
使用
Object.prototype.hasOwnProperty.call()
。使用 eslint(no-prototype-builtins 規則)等工具在您的代碼庫中強制實施這些做法。不要指望用戶發送完美、安全的數據。
在您鏈接的文章中,作者提到了這個確切的想法:
...來自用戶的數據應始終進行過濾和清理。
添加回答
舉報