如何解决Electron项目npm audit fix修复原型污染漏洞失败问题
你遇到的toString('base64')执行失效、原型污染问题,和contextBridge改造没有直接关系,核心是传递依赖引入的存在CVE-2022-22912漏洞的低版本plist包:该漏洞会通过原型链污染覆盖Object.prototype上的内置属性,直接导致Buffer、字符串的内置方法逻辑异常。
你手动在package.json顶层声明"plist": "^3.0.5"不生效、npm audit fix无法修复的原因很简单:Electron、electron-builder、serialport的嵌套依赖中锁死了<3.0.5版本的plist,npm默认的版本提升逻辑不会覆盖深层嵌套的被锁版本,顶层声明的依赖不会被嵌套依赖引用。
另外你贴的测试代码本身存在两个问题:一是console.log(str, str.toString('base64')末尾缺少右括号,运行会直接抛出语法错误;二是JavaScript原生字符串的toString()方法不接收编码参数,直接对字符串调用toString('base64')本身就会返回原字符串,做base64编码需要先将字符串转为Buffer对象再调用对应方法,不要把这个正常语言特性和原型污染故障混淆。
你当前使用的Node v16.15.1、npm v8.11.0、Electron v19.0.7组合完全支持contextBridge,不需要回退版本,按以下步骤操作即可修复:
- 在package.json的根层级添加
overrides字段,强制所有层级依赖使用修复了漏洞的plist版本(npm v8.3.0及以上版本原生支持该配置,你当前的npm版本完全适配):
{ "overrides": { "plist": "^3.0.5" } }
- 清空原有依赖和锁文件后重新安装:
rm -rf node_modules rm package-lock.json npm install
- 安装完成后执行
npm ls plist校验,确认所有层级引用的plist版本均>=3.0.5即可。 - 验证修复效果:在主进程入口最顶部执行测试代码,正常输出base64编码结果即说明修复完成:
const str = 'Many hands make light work'; console.log(Buffer.from(str).toString('base64')); // 预期输出:TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcms=
注:不要依赖
npm audit fix处理这类传递依赖漏洞,该命令只会升级符合语义化版本范围的直接依赖,无法处理被父依赖锁死版本的深层嵌套包。
如果因项目历史依赖兼容问题无法使用overrides方案,可选择以下经过生产验证的版本组合,全部原生支持contextBridge特性:
- 稳定优先组合:Node.js 16.13.2、npm 8.1.2、Electron 18.3.15,该组合下electron生态相关包默认依赖的plist已修复原型污染漏洞,serialport 10.x版本无需额外重编译即可正常运行。
- 旧依赖兼容组合:Node.js 14.21.3、npm 6.14.18、Electron 17.4.11,适配serialport 9.x及更早版本,无已知plist原型污染问题。
注意:不要为了临时绕过问题关闭上下文隔离、放开渲染进程的Node权限,这类操作只会放大原型污染漏洞的攻击面,无法解决根本问题。
内容的提问来源于stack exchange,提问作者puzzler

