Node模块API中读取用户传入对象属性是否存在安全风险?
是的,存在明确的安全风险!
你的代码在访问dataFromUser[key]时,确实可能被用户通过恶意构造的getter方法利用,进而触发危险操作。
问题出在哪?
JavaScript里的对象属性分两种:普通的数据属性,和带getter/setter的访问器属性。当你用obj[key]这种方式访问访问器属性时,对应的getter函数会立即执行。如果用户给你传一个藏了恶意getter的对象,你的代码在遍历属性、读取值的瞬间,就会触发这个getter里的恶意逻辑。
举个直观的例子,用户可以构造这样的对象:
const badObj = { get trap() { // 这里能执行任意操作——比如删文件、调用系统命令(只要进程有权限) require('fs').rmSync('/critical-file.txt'); return 'fake value'; } }; // 用户调用你的API时传入这个对象 myFunc(badObj);
当你的代码处理trap这个属性时,getter里的文件删除操作就会直接执行,这显然是致命的安全问题。
更糟的是,用户还能玩出更隐蔽的花样——比如修改原型链上的属性、覆盖Object.keys等,但最直接也最容易利用的就是恶意getter。
怎么修复?
如果你的需求只是获取对象自身的数据属性的值,不想触发任何getter,可以通过检查属性描述符来规避:
function myFunc(dataFromUser) { const dataArr = Object.keys(dataFromUser).map(key => { // 获取属性的完整描述符 const propDesc = Object.getOwnPropertyDescriptor(dataFromUser, key); // 只处理数据属性(没有getter的属性) if (propDesc && !propDesc.get) { return { name: key, value: propDesc.value }; } // 对访问器属性,可以选择忽略或返回占位值 return { name: key, value: '[accessor-property]' }; }); }
另外,还要注意防范原型链污染——比如用户可能给Object.prototype加恶意属性,导致Object.keys遍历到不该有的内容。这时候可以用Object.prototype.hasOwnProperty.call(dataFromUser, key)来确认属性是对象自身的,避免处理原型链上的属性。
总结
当前的代码完全没有对用户传入的属性类型做校验,直接访问属性值的行为相当于给了用户一个执行任意代码的入口。必须添加对访问器属性的过滤,才能避免被恶意利用。
内容的提问来源于stack exchange,提问作者Adelin
相关产品推荐
相关产品推荐

