Object.seal() 结合严格模式可精准锁定对象结构,防御动态属性注入攻击;它允许修改已有属性值,但禁止新增、删除属性或重定义描述符,错误在严格模式下立即报错暴露。

Object.seal() 结合严格模式,能在核心业务逻辑中有效防御动态属性注入攻击——关键不是“完全锁死”,而是精准锁定对象结构,让非法字段写入立即暴露、无法落地。
为什么动态属性注入是真实风险
常见于配置对象、用户输入映射、API 响应解析等环节。例如后端返回用户数据:{ id: 123, name: "Alice" },前端直接赋值给一个全局配置或状态对象,若未加防护,恶意脚本可能执行 user.role = "admin" 或 user.__proto__.isAdmin = true 等操作,篡改行为边界。
Object.seal() 不阻止属性赋值本身,但能确保:新增字段不生效、已有字段不可删改结构、错误在第一时间被捕捉——这正是防御链中最关键的“断点拦截”。
严格模式是 seal 发挥效力的前提
非严格模式下,obj.newField = value 或 delete obj.existing 会静默失败,开发者难以察觉问题;而严格模式强制报错,让异常浮出水面:
- 添加新属性 →
TypeError: Cannot add property xxx, object is not extensible - 删除现有属性 →
TypeError: Cannot delete property 'xxx' of # - 重定义属性描述符(如设
writable: false)→TypeError: Cannot redefine property 'xxx'
务必在密封前启用严格模式:"use strict"; 应置于函数作用域顶部或模块级顶部,避免遗漏。
典型业务场景中的密封实践
以权限配置对象为例:
"use strict";
const PERMISSIONS = {
canRead: true,
canEdit: false,
maxRetries: 3
};
Object.seal(PERMISSIONS);
// ✅ 安全:运行时可更新值(如开关调试)
PERMISSIONS.canEdit = true;
// ❌ 攻击失败:注入新字段被拦截
PERMISSIONS.isAdmin = true; // 严格模式下立即报错
// ❌ 攻击失败:尝试覆盖原型链或删除关键字段
delete PERMISSIONS.maxRetries; // 报错
PERMISSIONS.__proto__.bypass = 1; // 无效(且可能触发其他防护)
同理适用于:路由守卫参数、表单校验规则集、SDK 初始化选项、微前端通信 payload 模板等结构敏感对象。
注意浅层密封与递归加固
Object.seal() 只作用于目标对象自身,不递归处理嵌套对象。若配置含子对象(如 { api: { timeout: 5000 } }),需手动密封深层结构:
- 简单嵌套:对子对象单独调用
Object.seal() - 深度需求:封装递归密封函数(注意循环引用)
- 生产环境建议:配合
Object.freeze()用于只读常量,seal()用于“结构固定+值可变”的中间态
不复杂但容易忽略










