The Pug template engine is widely used in Node.js applications for rendering web pages dynamically. But a recent vulnerability—CVE-2024-36361—puts developers at serious risk if they use some Pug functions with untrusted inputs. Let’s break down what’s wrong, how it can be exploited, and what you should do about it.

What Is the Vulnerability?

Pug's template compiler functions—compileClient, compileFileClient, and compileClientWithDependenciesTracked—have a parameter called name. If a developer passes untrusted data (like something from user input) to this option, an attacker can inject and execute arbitrary JavaScript code on your server.

Does this affect my app?

Why Is This So Dangerous?

These Pug compiler functions turn Pug templates into JavaScript code. The name parameter actually ends up inside the generated JavaScript, so whatever string you place in name becomes code. If someone can mess with name, they can run _any_ JavaScript they want—in the context of your server.

Let’s see a risky example

const pug = require('pug');

// Simulate user input
const userTemplateName = req.body.name;   // BAD! Untrusted input

const compiledFn = pug.compileClient('p Hello World', {
  name: userTemplateName
});

Suppose userTemplateName is set to

foo"); console.log("You have been hacked!"); var dummyFunc = ("bar

The resulting generated client code will have your injected code inside it and will execute console.log("You have been hacked!") on the server.

Let’s manually do what an attacker could

const pug = require('pug');

const evilName = 'a"; console.log("Exploit!"); var b="c';

const code = pug.compileClient('p Test', { name: evilName });
console.log(code); // Look at the generated JS – it contains the injected code!

Check the output; you’ll see console.log("Exploit!") right inside the "client template" string.

Real Risk: Who Is Impacted?

Most apps are NOT vulnerable
Pug docs warn developers that these compile functions are intended to be used _by code under your control_. There's usually no reason to let any external (user) input near the name parameter. But:

If you dynamically create client-side templates from user input, you may be vulnerable.

- If your code passes filenames, resource identifiers, or similar from user data as template names, you’re also at risk.

Sanitize or strictly validate any data used as the name parameter.

3. Consider upgrading Pug when a patch for this CVE is released (check here for status).

Original References

- NVD Entry for CVE-2024-36361
- Pug Issue #3553 (GitHub)
- Pug compileClient documentation

Summary

CVE-2024-36361 is a classic case of how a simple design choice—trusting user input—can have far-reaching, dangerous consequences. If you ever use Pug compiler functions with the name parameter, double-check that no untrusted data can touch it. Most developers aren’t affected, but those who are face the risk of remote code execution on their servers.

Stay safe. Never trust user input where code will run.

Have questions?
Comment or reach out on the Pug GitHub. Let’s keep our node apps secure and our code clean!

Timeline

Published on: 05/24/2024 06:15:08 UTC
Last modified on: 08/02/2024 04:17:00 UTC