CodeBlanks Logo Icon CodeBlanks

Challenge - Secure app

JavaScript course · Expert · Lesson 63/63

Build a secure form app with XSS-safe rendering, CSP and input sanitization.

XSS-safe application

In this challenge you will build an XSS-safe form application. XSS is when an attacker injects a script into the page; the most common source is user input.

Always write user text with textContent, not innerHTML. textContent renders tags as plain text; the browser does not interpret them.

For stricter control you add a Content Security Policy (CSP) header: default-src 'self' blocks third-party and inline scripts. You also write a sanitize function that escapes the dangerous characters before binding input to the screen.

Exercise Safe render function

Write a sanitize(text) function that replaces &, < and > with their entity equivalents (escape & first). Then write renderSafe(container, text) that assigns the result of sanitize(text) to container.textContent. Finally add a meta tag whose http-equiv attribute is Content-Security-Policy and whose content attribute is default-src 'self'.

Show example solution
Start with function sanitize(text) { return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }. Then write function renderSafe(container, text) { container.textContent = sanitize(text); }. Finally add the tag <meta http-equiv="Content-Security-Policy" content="default-src 'self'">.

Example solution:
function sanitize(text) {
  return text
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
}

function renderSafe(container, text) {
  container.textContent = sanitize(text);
}

const cspTag = `<meta http-equiv="Content-Security-Policy" content="default-src 'self'">`;
document.head.insertAdjacentHTML('beforeend', cspTag);

Test yourself

  1. Which is safest against XSS?

    const el = document.querySelector('#out');
    // four options
    • el.textContent = userInput
    • el.innerHTML = userInput
    • el.insertAdjacentHTML('beforeend', userInput)
    • document.write(userInput)
    Show answer

    el.textContent = userInput — Correct! textContent writes tags as text; the browser does not interpret them as script.

  2. Safe text assignment

    const el = document.querySelector('#out');
    el.____ = userInput;
    Show answer
    const el = document.querySelector('#out');
    el.textContent = userInput;
  3. Match the security concepts

    textContent
    No tag parsing
    CSP header
    Source restriction
    sanitize
    Escape characters
    innerHTML
    Risky write

All lessons in Expert