Challenge - Secure app
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, '&').replace(/</g, '<').replace(/>/g, '>'); }. 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, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
}
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
-
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.
-
Safe text assignment
const el = document.querySelector('#out'); el.____ = userInput;Show answer
const el = document.querySelector('#out'); el.textContent = userInput; -
Match the security concepts
- textContent
- No tag parsing
- CSP header
- Source restriction
- sanitize
- Escape characters
- innerHTML
- Risky write