Why is this an issue?

Constructing templates by dynamically inserting strings coming from third-party sources is an anti-pattern which creates code that is brittle, difficult to read, and challenging to debug.

Moreover, in the long run, this practice progressively increases the likelihood of introducing Server-Side Template Injections (SSTI), sometimes in complex ways that are hard to detect.
An SSTI is the insertion of third-party data (like user data) within templates, which enables attackers to execute arbitrary commands on the underlying operating system.

How to fix it

It is recommended to standardize on safe template-building practices.
Separate logic from presentation by passing dynamic data to templates through a secure context or data-binding mechanism, rather than building the template string itself.

Code examples

Noncompliant code example

const pug = require('pug');

const pugTemplate = `
doctype html
html
  head
    title=${pageTitle}
  body
    ${userInput}
`;

const compiledFunction = pug.compile(pugTemplate); // Sensitive

compiledFunction();

Compliant Solution

const pug = require('pug');

const pugTemplate = `
doctype html
html
  head
    title= pageTitle
  body
    h1= mainHeading
    p.message= message
`;

const compiledFunction = pug.compile(pugTemplate);

const templateData = {
  pageTitle: 'Safe Template Example',
  mainHeading: 'Welcome!',
  message: 'This content is passed securely as data to the template.'
};
compiledFunction(templateData);

Resources

Standards