lodash漏洞修复-针对npm8以下低版本的问题修复

问题贴图:

出现以下提示说明你OK了,要是没出现那老师傅您接着往下瞧

1. 漏洞复现 

在本地你可以用以下代码在本地浏览器的控制台cv回车测试

const payload = '{"constructor": {"prototype": {"lodash": true}}}'
_.defaultsDeep({}, JSON.parse(payload))
if({}.lodash === true){ alert("Bad news :(\nYou're (still) vulnerable to Prototype Pollution") } else { alert("All Good! :)\nYou're NOT vulnerable (anymore) to Prototype Pollution") }

修复漏洞

第一种情况全局的lodash修复

这个好整,各位看官你直接cv以下代码升级您的lodash就好了

如果是项目中依赖的 lodash(在 node_modules 中),需要升级项目依赖:

# 使用 npm 升级到最新版本
npm install lodash@latest --save

# 使用 yarn 升级到最新版本
yarn add lodash@latest
如果有嵌套依赖(如其他包依赖旧版 lodash)你可以用npm ls lodash查看

如果说你的npm版本在8及以上的话您可以去看一看这位大神的版本,咱主要讲的是8以下的版本,这位大神的讲解很详细易懂,小编就是从这里学的

前端安全——最新:lodash原型漏洞从发现到修复全过程_lodash漏洞-优快云博客

npm8以下版本修复

新增一个本地 Node 脚本 scripts/force-resolutions.js 来实现与 npm-force-resolutions 类似的功能

/*
  Minimal force-resolutions for npm@6 lockfile (lockfileVersion: 1).
  - Reads package.json "resolutions"
  - Walks package-lock.json recursively and pins matching dependency names to the specified version
  - Removes resolved/integrity to force npm to re-resolve the tarball for that version

  Note: This intentionally ignores path-scoped resolutions (pkg>lodash or pkg/lodash) and pins by package name.
*/

const fs = require('fs');
const path = require('path');

const root = process.cwd();
const pkgPath = path.join(root, 'package.json');
const lockPath = path.join(root, 'package-lock.json');

function readJson(file) {
  return JSON.parse(fs.readFileSync(file, 'utf8'));
}

function writeJson(file, data) {
  fs.writeFileSync(file, JSON.stringify(data, null, 2) + '\n', 'utf8');
}

function collectResolutionVersions(resolutions) {
  const map = new Map();
  if (!resolutions || typeof resolutions !== 'object') return map;
  for (const [key, version] of Object.entries(resolutions)) {
    // Key may be "lodash" or "pkg>lodash" or "pkg/lodash"
    const parts = key.split(/[>\/]/);
    const name = parts[parts.length - 1];
    if (!name) continue;
    map.set(name, version);
  }
  return map;
}

function applyResolutionsToDeps(depTree, resolutionsMap) {
  if (!depTree || typeof depTree !== 'object') return;
  const deps = depTree.dependencies;
  if (!deps || typeof deps !== 'object') return;

  for (const [depName, depInfo] of Object.entries(deps)) {
    if (!depInfo || typeof depInfo !== 'object') continue;

    if (resolutionsMap.has(depName)) {
      const pinned = resolutionsMap.get(depName);
      depInfo.version = pinned;
      // Remove resolved/integrity to force re-resolution
      delete depInfo.resolved;
      delete depInfo.integrity;
    }
    // Recurse
    applyResolutionsToDeps(depInfo, resolutionsMap);
  }
}

function main() {
  if (!fs.existsSync(pkgPath) || !fs.existsSync(lockPath)) {
    console.error('[force-resolutions] package.json or package-lock.json not found');
    process.exit(0); // do not fail install
  }
  const pkg = readJson(pkgPath);
  const lock = readJson(lockPath);

  const resolutionsMap = collectResolutionVersions(pkg.resolutions);
  if (resolutionsMap.size === 0) {
    process.exit(0);
  }

  applyResolutionsToDeps(lock, resolutionsMap);
  writeJson(lockPath, lock);
  console.log('[force-resolutions] Applied resolutions to package-lock.json');
}

main();


package.json配置:

// 无需再安装全局或本地的 npm-force-resolutions
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "preinstall": "node scripts/force-resolutions.js"
  },
  "resolutions": {
    "lodash": "4.17.21",
    "html-webpack-plugin/lodash": "4.17.21",
    "pretty-error/lodash": "4.17.21",
    "renderkid/lodash": "4.17.21",
    "webpack-bundle-analyzer/lodash": "4.17.21",
    "http-proxy-middleware/lodash": "4.17.21",
    "webpack-merge/lodash": "4.17.21"
  },

请重新安装依赖:

cd src-frontend

del /q package-lock.json 2> NUL & rmdir /s /q node_modules 2> NUL

npm install

del这一行可能会报错,小编是新手还没来得及看原因,有哪位大佬知道刚好指导一下小编

可以替换为powershell指令:Remove-Item -Recurse -Force node_modules, package-lock.json

主要就是为了清除以前的node_modules和package-lock.json包避免出现一些杂七杂八的问题

删除后重新npm install再执行开始说的那段浏览器的代码就可以了

以上基本就可以解决问题,但是还有一种老六行为,小编就载到这里了,话不多说上图。

        element-ui里居然还有一份lodash, 关键element-ui这里2.15.14版本还是最新的。搞了半天我之前的研究半天的方法居然不是最终问题,那么在这里2.15.8的版本是没有这个引入的,也是下面这位博主发现的可不是我哦,可不能太看得起我了嘻嘻。

前端安全——最新:lodash原型漏洞从发现到修复全过程_lodash漏洞-优快云博客

以上内容全都是小编遇到的问题以及解决方法,感谢各位看官收看,小编是个前段新人,如果大佬们发现哪里有问题的,还请不吝指教,小编一定努力学习@!!!!!

lodash 是一个广泛使用的 JavaScript 实用工具库,它提供了许多用于处理数组、对象、字符串等功能的函数。然而,在 2018 年至 2020 年期间,研究人员发现了一些版本中的原型链污染(Prototype Pollution)漏洞,并且在特定条件下可以导致远程代码执行(RCE)。这些漏洞主要源于某些函数对用户输入的不安全处理,允许攻击者通过构造恶意输入来修改 `Object.prototype`,从而影响整个应用程序的行为。 ### 漏洞详情 #### 原型链污染原理 JavaScript 使用原型继承模型,所有对象都链接到一个“原型”对象。当访问对象的属性时,如果该对象本身没有这个属性,JavaScript 引擎会查找其原型对象,依此类推,直到找到属性或到达原型链的末端。攻击者可以利用这一点,通过构造特定的数据结构将恶意属性注入到 `Object.prototype` 中。一旦成功,后续的代码逻辑可能会无意中使用这些恶意属性,从而引发异常行为,甚至执行任意代码 [^1]。 #### lodash 中受影响的函数 在 lodash 的 4.17.16 版本之前,`zipObjectDeep` 函数存在原型链污染问题。此函数用于将两个数组合并为一个对象,其中键和值可以通过嵌套路径表示法进行指定。例如: ```javascript _.zipObjectDeep(['a[0].b', 'a[1].c'], [1, 2]); // 结果: { a: [{ b: 1 }, { c: 2 }] } ``` 由于该函数未能正确校验路径表达式,攻击者可以构造类似 `__proto__.constructor.prototype` 的路径,向 `Object.prototype` 注入任意属性,进而可能导致 RCE [^1]。 #### 攻击场景与影响 在某些 Web 应用程序中,如果开发者错误地信任了来自客户端的 JSON 数据,并将其直接传递给 lodash 的易受攻击函数,攻击者就可以通过构造特殊的 JSON 输入来触发原型链污染。例如,以下是一个典型的 payload: ```json { "type": "test", "content": { "prototype": { "constructor": { "a": "b" } } } } ``` 这种 payload 可能会导致全局对象被修改,从而影响其他依赖于标准原型的对象行为。在极端情况下,如果应用程序中存在动态代码求值(如 `eval()` 或 `new Function()`),攻击者可能进一步实现远程代码执行 [^4]。 --- ### 修复方案 #### 升级版本 官方在 **lodash v4.17.19** 中修复了相关漏洞。建议用户尽快升级到最新版本以避免潜在风险。新版本中,`zipObjectDeep` 等函数增加了对路径表达式的严格校验,防止非法路径操作。 #### 手动修补 对于无法立即升级的项目,可以通过以下方式手动缓解: - 避免将不可信数据直接传入 `_.zipObjectDeep` 等函数。 - 在解析 JSON 输入前,使用白名单机制过滤掉包含 `__proto__` 或 `constructor` 的字段。 - 使用 `Object.freeze(Object.prototype)` 来冻结原型链,防止外部修改。需要注意的是,这种方法是浅层冻结,仅能阻止直接添加/修改属性,不能阻止嵌套对象的修改 [^2]。 #### 安全编码实践 为了从根本上减少原型链污染的风险,开发人员应遵循以下最佳实践: - 对所有用户输入进行严格的验证和清理。 - 尽量避免使用 `eval()`、`new Function()` 等危险的代码执行方法。 - 使用现代框架(如 React、Vue)自带的安全机制来处理模板渲染和数据绑定。 - 启用内容安全策略(CSP),限制内联脚本和外部资源加载。 --- ### 示例:检测原型污染 以下是一个简单的测试脚本,可用于检测是否存在原型链污染漏洞: ```javascript const _ = require('lodash'); console.log('Before:', {}.polluted); // undefined _.zipObjectDeep(['__proto__.polluted'], ['yes']); console.log('After:', {}.polluted); // 'yes' if vulnerable ``` 如果输出为 `'yes'`,则说明当前环境存在原型链污染漏洞--- ### 总结 lodash 的原型链污染漏洞暴露了 JavaScript 生态系统中常见的安全隐患。虽然官方已及时修复,但仍需引起足够重视。开发者应在日常开发中加强安全意识,合理使用第三方库,并定期更新依赖项以确保应用安全。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值