柯里化不能防范原型链污染,它仅是参数预设技术,不干预原型写入或冻结;有效防护需输入清洗、object.create(null)隔离、冻结关键原型及替换高危工具函数。

柯里化本身不能直接防范原型链污染,它不是安全机制,也不影响原型链结构或属性写入行为。把柯里化当作“防御原型污染的手段”是一种常见误解——污染发生在对象创建、属性赋值、深拷贝等环节,而柯里化只是函数参数预设的技术,两者作用域和攻击面完全不同。
为什么柯里化对原型污染无效
原型链污染的核心是:攻击者通过可控输入(如 JSON 字符串、URL 参数)向 Object.prototype 或其他内置原型(如 Array.prototype、Element.prototype)写入属性,导致所有实例意外继承恶意行为。这个过程不涉及函数调用逻辑,也不依赖参数绑定顺序。
柯里化改变的是函数调用方式,比如把 fn(a, b, c) 变成 fn(a)(b)(c),但它既不阻止 __proto__ 被赋值,也不干预 JSON.parse() 后的合并操作,更无法冻结原型或过滤敏感键名。
真正有效的防护组合
防范原型污染必须从输入、对象创建、运行时环境三方面入手,以下才是经过验证的实用做法:
-
输入层清洗:所有外部数据(
req.body、location.search、JSON.parse()结果)进入业务逻辑前,递归扫描并移除含__proto__、constructor、prototype的键及嵌套路径,推荐正则:/\b(__proto__|constructor|prototype)\b/i -
对象创建隔离:配置类、缓存、映射表等纯字典场景,一律用
Object.create(null)替代{},从源头切断原型链依赖 -
运行时冻结关键原型:在页面或服务启动最早期(
<script></script>第一行 / Node.js 入口第一行),执行:Object.freeze(Object.prototype);Object.freeze(Array.prototype);Object.freeze(Element.prototype);
(注意:必须早于任何第三方脚本,否则无效) -
替换高危工具函数:禁用旧版
lodash.merge等默认允许原型键的合并方法;浅拷贝用Object.assign({}, input);深拷贝优先用structuredClone()(现代环境)或自定义跳过敏感键的实现
柯里化能间接帮上什么忙?
它唯一可能起作用的场景,是配合白名单校验做参数约束封装,例如:
你有一个配置合并函数 mergeConfig(target, source),担心 source 来自用户输入。可以柯里化出一个“安全版本”:
const safeMerge = curry((whitelist, target, source) => {
const cleaned = filterKeys(source, whitelist); // 过滤非白名单字段
return Object.assign(target, cleaned);
});
// 使用时只传预设白名单
const mergeUserSettings = safeMerge(['theme', 'lang', 'notifications']);
但这本质上仍是靠 filterKeys 和白名单起作用,柯里化只是让调用更简洁,不是防护主体。
需要立即停用的错误思路
不要尝试用柯里化“包裹” toString、hasOwnProperty 等方法来防篡改——这些方法一旦被覆盖(如 Element.prototype.closest = () => null),柯里化后的函数照样调用被劫持的版本。真正要锁死的是原型对象本身,不是函数调用形式。











