reflect本身不防攻击,但配合冻结原型、输入过滤和proxy拦截可构建可审计难绕过的防护链;需最早期冻结object/array/function.prototype,数据用object.create(null),json解析后清洗敏感键,proxy+reflect实现访问日志,动态调用前校验类型与存在性。

Reflect 本身不防攻击,但它配合冻结原型、输入过滤和 Proxy 拦截,能构建出可审计、可验证、难绕过的防护链。关键不是“用 Reflect 就安全”,而是用它把原本隐式、易漏的操作变成显式、可判断、可记录的步骤。
冻结原型是第一道硬隔离
所有后续防护都建立在原型不可写的基础上。必须在页面加载最早期(任何第三方脚本执行前)冻结核心原型:
-
Object.freeze(Object.prototype)—— 阻断对所有对象行为的全局污染 -
Object.freeze(Array.prototype)、Object.freeze(Function.prototype)—— 防止数组方法或函数行为被劫持 - 避免只冻 Object.prototype:攻击者可能通过
[] instanceof Array触发 Array.prototype 上的恶意方法
配置与数据容器改用无原型对象
表单规则、API 响应映射、权限配置等纯数据结构,不要用 {},改用:
-
Object.create(null)创建无原型对象,天然免疫__proto__和constructor传导 - 校验时用
Object.prototype.hasOwnProperty.call(obj, key)替代obj.hasOwnProperty(key),避免被污染的 hasOwnProperty 覆盖 - JSON 解析后立即清洗:递归遍历键名,移除
__proto__、constructor、prototype及其大小写变体(如__PROTO__)
用 Proxy + Reflect 实现可审计的访问日志
真正合规审计需要留痕。Proxy 拦截所有属性读写,Reflect 保证语义正确,二者组合可记录谁、何时、访问/修改了什么:
- 在
gettrap 中调用Reflect.get(target, key, receiver),同时记录key、target.constructor.name、时间戳 - 在
settrap 中先校验key是否在白名单内,再调用Reflect.set(...),失败时上报异常并拒绝 - 禁止直接操作
target[key]:它会绕过 getter/setter、忽略属性描述符、丢失receiver绑定,导致审计日志与实际行为不一致
动态调用必须前置类型与存在性校验
前端常需根据配置执行回调(如按钮点击 handler、校验函数),这类动态调用是反射攻击的高危入口:
- 调用前必须检查:
typeof config.handler === 'function',不能只判真值 - 显式传入
thisArg,避免非严格模式下绑定到全局对象;空参数列表传[],不传undefined - 包裹
try/catch,返回结构化结果(如{ success: false, error: 'xxx' }),便于日志归集与监控告警
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











