Sling Academy
Home/Node.js/Node.js: Escape dangerous HTML content in Pug templates

Node.js: Escape dangerous HTML content in Pug templates

Last updated: February 06, 2024

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.

Next Article: NodeJS: Using express-fileupload to simply upload files

Previous Article: Using ExpressJS and Multer with TypeScript

Series: Node.js & Express Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates