Node.js: Escape dangerous HTML content in Pug templates

Updated: February 6, 2024 By: Guest Contributor Post a comment

Introduction

When developing web applications with Node.js and Pug as the templating engine, it’s crucial to consider security measures to prevent possible attacks, such as Cross-Site Scripting (XSS). In this guide, we’ll explore how to escape dangerous HTML content in Pug templates, ensuring your web application remains secure against such vulnerabilities.

Let’s dive into the essentials of escaping HTML content and implement practical examples to reinforce our understanding.

Understanding HTML Escaping

HTML escaping refers to the process of encoding certain characters that could be interpreted as HTML or JavaScript, into a format that’s simply displayed as plain text on the webpage. Characters like <, >, &, and " are commonly escaped to their respective HTML entities to prevent browsers from executing them as code.

Why Escape HTML in Pug?

Pug, formerly known as Jade, is widely used with Node.js for server-side templating. While Pug automatically escapes variables outputted to templates, direct user input can still pose a risk if not properly handled. Ensuring all user-generated content is escaped prevents XSS attacks, whereby malicious scripts are injected into webpages viewed by others.

Example: Basic Escaping in Pug

//- index.pug
p= userContent

In the above example, userContent could be a variable containing user input. Pug automatically escapes this by converting potentially dangerous characters into their HTML entity equivalents. This renders the input safe for displaying.

Manual Escaping

Although Pug does a great job at auto-escaping, there are instances where you might need to manually escape content, especially when using template literals or when incorporating variables into attributes.

//- Manually escaping dynamic URLs
a(href=`https://example.com/profile?user=${encodeURIComponent(userId)}`) Profile

Here, we use encodeURIComponent to escape the userId variable in the URL, making it safe for inclusion in an attribute.

Displaying Unescaped HTML

There might be situations where you want to deliberately display HTML content without escaping (e.g., rendering articles with HTML formatting). Pug offers a syntax for this, but use it judiciously.

//- index.pug
p!= trustedHtmlContent

The != tells Pug to output the content without escaping. This should only be used for content that’s been sanitized or is coming from a trusted source.

Sanitizing HTML Content

When you really need to insert raw HTML into your templates from user input, it’s essential to sanitize it first. Sanitization libraries like sanitize-html or DOMPurify can be used on the server-side before passing the HTML to the template.

// Sanitizing with sanitize-html
const sanitizeHtml = require('sanitize-html');
const cleanHtml = sanitizeHtml(dirtyHtml, {
  allowedTags: ['b', 'i', 'em', 'strong', 'a'],
  allowedAttributes: {
    'a': ['href']
  }
});

In the code snippet above, sanitize-html is used to remove potentially dangerous tags and attributes from dirtyHtml, ensuring only simple formatting tags are allowed.

Putting It All Together

Let’s create a simple web application with Node.js and Pug that incorporates everything we’ve discussed. This example will include user input that is properly escaped and displayed:

// Server setup
const express = require('express');
const app = express();

app.set('view engine', 'pug');

app.get('/', (req, res) => {
  const userContent = '<script>alert("XSS")</script>';
  res.render('index', { userContent: userContent });
});

app.listen(3000, () => console.log('Server running on port 3000'));

This basic setup demonstrates how user input can be safely incorporated into Pug templates. Remember, the key is always to sanitize input where necessary and escape accordingly to prevent security vulnerabilities.

Conclusion

Escaping HTML content in Pug templates is crucial for maintaining web application security. By following the practices outlined in this guide, developers can mitigate XSS risks and ensure a safer browsing experience for end-users. Always sanitizes user input, escape appropriately and use Pug’s automatic escaping features to help safeguard your applications.