系统测试前发现漏洞!
利用公司的漏扫对系统进行扫描,发现高危漏洞两个竟都是lodash引发,这是漏洞详细报告:
html
Attack Details:lodash v4.17.10-4.17.10Vulnerability DescriptionLodash versions prior to 4.17.21 are vulnerable to Command Injection via the template function.
Discovered by/deepscan/javascript_library_audit_deepscan.js
ClassificationCWECWE-770CVECVE-2019-1010266CVSS v3.1Base Score:6.5 -CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:HAttack Vector:NetworkAttack Complexity:LowPrivileges Required:LowUser Interaction:NoneScope:UnchangedConfidentiality:NoneIntegrity:NoneAvailability:HighAttack Vector:NetworkAttack Complexity:LowPrivileges Required:LowUser Interaction:NoneScope:UnchangedConfidentiality:NoneIntegrity:NoneAvailability:HighWeb References
CVE-2021-23337
漏洞排查过程
这个漏洞是说
lodash
4.17.10的版本(4.17.21 之前版本 ) 中的_.template
函数存在 命令注入(Command Injection)漏洞 。攻击者可以通过精心构造的输入在模板中执行任意 JavaScript 代码,可能导致 远程代码执行(RCE) 或 服务拒绝(DoS) 。
检查package.json
查看项目中package.json
文件中没有显示引入lodash
,估计是某个依赖的依赖。 首先我查看了项目的package.json文件,确认我们没有直接安装Lodash,怀疑是lodash是某个依赖的依赖。 检查package-lock.json 发现项目中确实有lodash,但版本是4.17.21,而漏洞报告指出的是4.17.10及以下版本存在风险。这似乎不匹配。
检查实际安装的lodash版本
js
npm list lodash
输出:
js
| | +-- lodash@4.17.21 deduped
| | `-- pretty-error@2.1.2
| | +-- lodash@4.17.21 deduped
| | `-- renderkid@2.0.7
| | `-- lodash@4.17.21 deduped
| +-- portfinder@1.0.32
| | `-- async@2.6.4
| | `-- lodash@4.17.21 deduped
| +-- webpack-bundle-analyzer@3.9.0
| | `-- lodash@4.17.21 deduped
| +-- webpack-dev-server@3.11.3
| | `-- http-proxy-middleware@0.19.1
| | `-- lodash@4.17.21 deduped
| `-- webpack-merge@4.2.2
| `-- lodash@4.17.21 deduped
+-- ant-design-vue@1.7.8
| +-- lodash@4.17.21 deduped
| `-- node-emoji@1.11.0
| | +-- lodash@4.17.21 deduped
| | `-- pretty-error@2.1.2
| | +-- lodash@4.17.21 deduped
| | `-- renderkid@2.0.7
| | `-- lodash@4.17.21 deduped
| +-- portfinder@1.0.32
| | `-- async@2.6.4
| | `-- lodash@4.17.21 deduped
| +-- webpack-bundle-analyzer@3.9.0
| | `-- lodash@4.17.21 deduped
| +-- webpack-dev-server@3.11.3
| | `-- http-proxy-middleware@0.19.1
| | `-- lodash@4.17.21 deduped
| `-- webpack-merge@4.2.2
| `-- lodash@4.17.21 deduped
| | `-- lodash@4.17.21 deduped
| +-- portfinder@1.0.32
| | `-- async@2.6.4
| | `-- lodash@4.17.21 deduped
| +-- webpack-bundle-analyzer@3.9.0
| | `-- lodash@4.17.21 deduped
| +-- webpack-dev-server@3.11.3
| | `-- http-proxy-middleware@0.19.1
| | `-- lodash@4.17.21 deduped
| +-- portfinder@1.0.32
| | `-- async@2.6.4
| | `-- lodash@4.17.21 deduped
| +-- webpack-bundle-analyzer@3.9.0
| | `-- lodash@4.17.21 deduped
| +-- webpack-dev-server@3.11.3
| | `-- http-proxy-middleware@0.19.1
| | `-- lodash@4.17.21 deduped
| `-- webpack-merge@4.2.2
| `-- lodash@4.17.21 deduped
| `-- webpack-merge@4.2.2
| `-- lodash@4.17.21 deduped
+-- ant-design-vue@1.7.8
| +-- lodash@4.17.21 deduped
| `-- node-emoji@1.11.0
| `-- lodash@4.17.21 deduped
`-- eslint-plugin-vue@8.7.1
`-- vue-eslint-parser@8.3.0
`-- lodash@4.17.21 deduped
根本没有任何依赖lodash版本是4.17.10,这就见鬼了,吐槽过后仔细一想肯定是某个依赖把lodash代码下载到源码里了!于是全局搜索4.17.10,果真找到了!

解决漏洞
确认问题来源后,我需要解决这个安全隐患。由于Element-UI已经将lodash打包进自己的源码,常规的npm更新无法解决这个问题。我采取了以下步骤:
-
使用patch-package修改Element-UI源码
首先安装patch-package:
luanpm install patch-package --save-dev
-
修改node_modules中的文件
找到
node_modules/element-ui/lib/utils/lodash.js
,将顶部的版本信息从4.17.10改为4.17.21(安全版本)。 -
创建补丁文件
执行:
gonpx patch-package element-ui
这会在项目根目录下创建
patches
文件夹,包含对element-ui的修改补丁。 -
在package.json中添加postinstall脚本
json"scripts": { "postinstall": "patch-package" }
这样每次npm install后会自动应用我们的补丁。
为什么Element-ui会包含漏洞?
经过调查,我发现Element-UI为了减少外部依赖和提高性能,选择将lodash的部分功能直接打包进自己的源码中。这种做法虽然减少了包体积和依赖复杂度,但也带来了安全隐患:
- 隐藏的依赖:开发者很难意识到项目中存在老版本的lodash
- 无法通过常规方式更新:即使lodash发布了安全补丁,内置版本的库也无法通过npm update更新
- 缺乏透明度:除非仔细检查源码,否则很难发现这种"打包"的依赖
总结
这次安全排查经历让我学到了几个重要的经验:
- 安全扫描工具只能指出问题,不能定位问题:需要开发者深入分析漏洞的真正来源
- 间接依赖同样危险:即使没有直接安装某个库,它仍可能通过其他依赖引入
- 源码打包的依赖需要特别关注:它们绕过了npm的版本管理机制
- patch-package是解决第三方库问题的有效工具:当无法等待官方更新时,可以临时使用
对于UI库这类基础依赖,建议:
- 定期检查官方安全公告
- 考虑使用npm audit等工具进行安全检查
- 对于关键项目,可以fork维护自己的安全版本
希望这次经历能帮助其他遇到类似问题的开发者!如果你也发现了Element-UI的这个隐患,不妨尝试上述解决方案。