You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ember 2.18.0中能否重写Ember.set() API检测原型污染?

在Ember 2.18.0中避免Ember.set原型污染的替代方案

由于无法直接重写Ember.set API,可通过以下几种可行方案实现危险参数的检查:

1. 封装安全版Set工具函数

创建一个全局的安全设置函数,替代所有直接调用Ember.set的场景,在函数内部先完成不安全key的校验,再调用原生Ember.set:

// app/utils/safe-set.js
export default function safeSet(obj, key, value) {
  // 定义禁止设置的危险key列表
  const unsafeKeys = ['__proto__', 'constructor', 'prototype'];
  if (unsafeKeys.includes(key)) {
    // 根据业务需求选择:抛出错误/忽略操作/打日志
    throw new Error(`禁止设置危险属性:${key}`);
  }
  return Ember.set(obj, key, value);
}

使用时直接导入并替换Ember.set:

import safeSet from 'app/utils/safe-set';

// 替代 Ember.set(obj, 'someKey', value)
safeSet(obj, 'someKey', value);

注意:需要梳理项目中所有Ember.set的调用点,逐步替换,适合长期迭代优化。

2. 全局覆盖Ember.set(谨慎使用)

如果项目允许修改全局Ember对象的方法引用,可以在应用初始化阶段覆盖Ember.set,注入校验逻辑:

// app/initializers/safe-set.js
export function initialize() {
  const originalSet = Ember.set;
  Ember.set = function(obj, key, value) {
    const unsafeKeys = ['__proto__', 'constructor', 'prototype'];
    if (unsafeKeys.includes(key)) {
      console.warn(`拦截危险属性设置:${key}`);
      // 可选:直接返回,不执行设置操作
      return obj;
    }
    return originalSet(obj, key, value);
  };
}

export default {
  name: 'safe-set',
  initialize
};

注意:这种方式会影响所有调用Ember.set的代码,需充分测试原有功能是否受影响,避免破坏Ember内部的属性处理逻辑。

3. 用Proxy包装目标对象

利用ES6 Proxy拦截对象的属性设置操作,即使通过Ember.set赋值也会经过校验:

// app/utils/safe-proxy.js
export default function createSafeProxy(obj) {
  return new Proxy(obj, {
    set(target, prop, value) {
      const unsafeKeys = ['__proto__', 'constructor', 'prototype'];
      if (unsafeKeys.includes(String(prop))) {
        throw new Error(`尝试设置不安全属性:${prop}`);
      }
      // 调用Ember.set确保符合Ember的属性系统规则
      Ember.set(target, prop, value);
      return true;
    }
  });
}

使用时将需要保护的对象用Proxy包裹:

import createSafeProxy from 'app/utils/safe-proxy';

const myObj = createSafeProxy(Ember.Object.create());
Ember.set(myObj, 'normalKey', 'value'); // 正常执行
Ember.set(myObj, '__proto__', {}); // 抛出错误

注意:Ember 2.18兼容ES6 Proxy(需确保目标浏览器支持),但Proxy可能会干扰Ember内部的元数据追踪,建议仅在特定敏感对象上使用。

4. 为Ember对象添加Mixin扩展

创建一个包含安全设置方法的Mixin,让需要保护的类混入该Mixin,通过实例方法而非全局Ember.set操作属性:

// app/mixins/safe-set.js
export default Ember.Mixin.create({
  safeSet(key, value) {
    const unsafeKeys = ['__proto__', 'constructor', 'prototype'];
    if (unsafeKeys.includes(key)) {
      console.error(`非法属性设置:${key}`);
      return;
    }
    this.set(key, value); // 调用Ember对象的实例set方法
  }
});

在类中使用Mixin:

import Ember from 'ember';
import SafeSetMixin from 'app/mixins/safe-set';

export default Ember.Component.extend(SafeSetMixin, {
  someAction() {
    // 替代 this.set('key', value)
    this.safeSet('key', value);
  }
});

注意:仅适用于Ember.Object的子类(组件、控制器、模型等),无法覆盖全局Ember.set的调用。

内容的提问来源于stack exchange,提问作者Blg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:03:13