跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何利用 new.target 确保敏感的加密模块永远无法被非法直接调用

可通过 new.target 拦截构造调用,禁止直接实例化 SecureCipher,仅允许可信子类继承;需结合 purpose 静态属性校验、原型标识验证、初始化检查及上下文冻结等多重机制保障安全性。 可以利用
new.target
在构造函数中做“调用来源拦截”,让加密模块只允许被可信子类继承使用,禁止任何直接实例化行为——这是防止非法调用最轻量、最可靠的一道防线。 核心思路:拒绝 new Parent(),只放行 new Child() 敏感加密模块(如
SecureCipher
)不应是可直接实例化的工具类,而应是抽象基类。通过
new.target
判断调用者身份: 若
new.target === SecureCipher
,说明有人写了
new SecureCipher(...)
—— 立即抛出
TypeError
若
new.target !== SecureCipher
,说明是子类(如
PaymentCipher
)在调用
super()
—— 允许继续执行,但需配合后续校验 强制子类声明用途与合规性 仅靠
new.target
不足以防伪。必须叠加约定机制,确保子类不是空壳继承: 要求子类定义静态属性
purpose = 'payment' | 'auth' | 'pci-dss'
,父类构造中检查该属性是否存在且合法 检查
new.target
是否有特定原型标识,例如
new.target.prototype[Symbol.for('isApprovedCipher')] === true
结合
Reflect.getPrototypeOf(new.target)
验证继承链是否包含预设的受信基类(避免伪造子类) 搭配初始化校验,堵住绕过漏洞 即使子类通过了
new.target
检查,仍需防止其跳过关键初始化。可在父类构造末尾加入: 检查
this._initialized
是否为
true
(由子类
super()
后显式设置) 调用
this.init?.()
并校验返回值是否符合预期(如返回
{ ready: true, mode: 'aes-256-gcm' }
) 若校验失败,立即清空内部密钥缓存(
this._key = null
)并抛出错误,使实例处于不可用状态 增强防篡改:绑定构造时上下文 进一步降低运行时劫持风险: 在构造函数开头记录
const callSite = new.target.name
,后续敏感方法(如
encrypt()
)校验该名称未被动态改写 用
Object.freeze(Object.getPrototypeOf(this))
锁定原型,阻止运行时注入或替换方法 对关键字段(如
this._cipherKey
)使用
Object.defineProperty
设为不可配置、不可枚举、只读

相关文章