应直接用 Object.hasOwn(obj, key) 替代 obj.hasOwnProperty(key),因其不依赖原型链、不调用可能被篡改的实例方法,可彻底规避原型污染导致的属性检测失效问题。

直接用 Object.hasOwn(obj, key) 替代 obj.hasOwnProperty(key),就能从根源上避开原型污染导致的属性检测失效问题。它不依赖对象原型链,也不调用可能被篡改的实例方法,只检查对象自身是否定义了该属性。
为什么 hasOwnProperty 不安全
因为 hasOwnProperty 是挂载在 Object.prototype 上的方法,一旦原型被污染(比如 Object.prototype.hasOwnProperty = () => false),所有普通对象调用它都会返回错误结果。更常见的情况包括:
- 对象自身定义了同名属性,如
{ hasOwnProperty: 'hacked' },调用直接返回字符串而非布尔值 - 使用
Object.create(null)创建的对象根本没有这个方法,调用即抛TypeError - 第三方库或用户输入对象可能已重写该方法,导致白名单校验、配置过滤等逻辑静默失败
Object.hasOwn 的正确用法
它是 ES2022 正式引入的静态方法,语义明确、行为稳定:
- 语法统一:
Object.hasOwn(obj, 'key'),返回true或false - 支持
Symbol键:需传原始值,如const sym = Symbol('x'); Object.hasOwn(obj, sym) - 对
null或undefined第一个参数会明确抛TypeError,便于及时发现传参错误 - 天然兼容
Object.create(null)对象,无需额外处理
哪些地方必须立刻替换
以下场景一旦受原型污染,就可能引发权限绕过、配置覆盖、序列化泄露等严重问题:
立即学习“Java免费学习笔记(深入)”;
- 用户输入字段白名单校验,如
if (Object.hasOwn(data, 'username')) - 配置对象安全访问,如
if (Object.hasOwn(config, 'timeout')) - 遍历对象前过滤原型属性,替代
for...in中的obj.hasOwnProperty(key) - 序列化前确认关键字段是否为自有属性,避免意外序列化被污染的原型字段
兼容旧环境的安全降级方案
现代环境(Chrome 93+、Firefox 97+、Safari 16.4+、Node.js 16.9+)已原生支持。若需兼容更早版本,推荐以下写法:
const hasOwn = Object.hasOwn || ((obj, key) => Object.prototype.hasOwnProperty.call(Object(obj), key));
关键点:
-
Object(obj)将null或undefined转为空对象,避免调用时报错 - 不直接引用
obj.hasOwnProperty,彻底规避原型污染影响 - 不推荐用
obj?.hasOwnProperty?.(key),原型被设为null时仍会抛错
文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/xinjizixun/123544.html