Description
Cross-site scripting (XSS) can occur when user input is inserted into an HTML template string without suitable encoding. An attacker can supply markup or scripts that run in another user's browser, exposing information or compromising a session.
Potential impact
- Scripts may steal accessible cookies, session tokens or information entered on the page.
- Injected HTML or scripts may alter the page, disrupt its behavior or present phishing content.
Remediation
- When inserting text into an HTML body, use HTML encoding for that context or the template engine's automatic escaping.
- If markup is unnecessary, use
textContentinstead ofinnerHTML. UsesetAttributeonly with fixed, non-executable attribute names; validate URL schemes and destinations separately. - If HTML markup must be allowed, restrict tags and attributes with an HTML sanitizer such as DOMPurify. Sanitization differs from text encoding, and ordinary HTML escaping must not be reused for JavaScript or CSS contexts.
Examples
Before
javascript
const userInput = '<img src="x" onerror="alert(1)">'; // Malicious input
const message = `<div>${userInput}</div>`;
document.body.innerHTML = message;
After
javascript
function escapeHtml(str) {
return str.replace(/[&<>'"]/g, function (c) {
return {
"&": "&",
"<": "<",
">": ">",
"'": "'",
'"': """,
}[c];
});
}
const userInput = '<img src="x" onerror="alert(1)">'; // Malicious input
const message = `<div>${escapeHtml(userInput)}</div>`;
document.body.innerHTML = message;
Explanation:
- Before: The markup in
userInputis inserted directly into HTML and may execute in the browser. - After:
escapeHtmlencodes the input for the HTML body in this example, so the supplied tags are displayed as text.