Description
Passing user-controlled strings as HTML to jQuery's html(), append(), prepend(), wrap(), wrapInner(), wrapAll(), before() or after() may execute malicious markup. globalEval() executes strings as code, while getScript() fetches and executes a script from a URL; the code and URL need separate trust checks.
Potential impact
- Malicious scripts may expose accessible cookies or authentication information.
- An attacker may compromise a session and act with the user's permissions.
- Injected HTML or JavaScript may deceive users with phishing content.
Remediation
- Use
text()for text and purpose-specific APIs such asval()for form values. - Encode text for an HTML body; if actual HTML must be allowed, restrict it with a trusted sanitizer.
- Do not pass external input to
globalEval(). Use only fixed, trusted script URLs withgetScript(). HTML escaping cannot secure code execution or validate script URLs.
Examples
Before
javascript
// Pass user input directly to a DOM manipulation method
function vulnerable(userInput) {
$("#container").html(userInput); // XSS risk
}
// Another example
const hash = window.location.hash;
$("div").append(hash); // Risk depends on the actual value interpreted as HTML
After
javascript
// Use text() to display text
function safe(userInput) {
$("#container").text(userInput); // Display as text
}
// Alternatively, escape before HTML insertion
function escapeHTML(str) {
return String(str).replace(/[&<>'"]/g, function (c) {
return {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
}[c];
});
}
function safeWithEscape(userInput) {
$("#container").html(escapeHTML(userInput)); // Insert after escaping
}
Explanation:
- Before: Untrusted values reach APIs that interpret HTML. Current browsers do not percent-decode a URL fragment when it is read, so encoded tags in
window.location.hashalone do not establish script execution. Check how the actual HTML value is constructed, including any separate decoding. - After:
text()or escaping for the HTML body displays values as text at this output location.