CodeBlanks Logo Icon CodeBlanks

XSS-safe rendering

JavaScript course · Expert · Lesson 33/63

Show user input safely with textContent and an escape function.

Why textContent?

innerHTML parses text as HTML, so a <script> tag or event attribute in the text leads to an XSS attack.

textContent inserts text as plain text; tags appear as characters and no script runs.

For extra safety we'll also write an escapeHtml function that converts &, <, > into HTML entities.

The escapeHtml function

The escapeHtml function converts three dangerous characters into HTML entities: the & sign and the less-than and greater-than characters. This way tags in user text appear as text on screen and don't run as scripts.

The function is written as an arrow function and returns a replace chain. Each replace call takes the previous result and applies the next change.

This layer together with textContent provides defense in depth: if one layer is bypassed, the other still protects.

Exercise Write safe rendering

Write an escapeHtml arrow function that converts &, <, > into HTML entities (with a replace chain). Then write a renderComment(text) function: create a paragraph with document.createElement("p"), set .textContent = text to insert it safely, and append it with commentsEl.appendChild(p).

Show example solution
const escapeHtml = (str) => str
  .replace(/&/g, "&amp;")
  .replace(/</g, "&lt;")
  .replace(/>/g, "&gt;");

function renderComment(text) {
  const p = document.createElement("p");
  p.textContent = text;
  commentsEl.appendChild(p);
}

Test yourself

  1. Which is safe for user text?

    el.____ = userInput;
    • element.innerHTML = text
    • element.insertAdjacentHTML = text
    • document.write(text)
    • element.textContent = text
    Show answer

    element.textContent = text — Correct! textContent doesn't parse HTML, it's XSS-safe.

  2. escapeHtml replace

    const escapeHtml = (str) => str
      .replace(/</g, "____")
      .replace(/>/g, "&gt;");
    Show answer
    const escapeHtml = (str) => str
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;");
  3. Match characters to entities

    &
    &amp;
    <
    &lt;
    >
    &gt;
    "
    &quot;

All lessons in Expert