DOM-Based XSS Vulnerabilities
DOM-Based XSS Vulnerabilities
DOM-based Cross-Site Scripting (XSS) represents one of the most prevalent JavaScript security vulnerabilities. Unlike traditional XSS that occurs on the server side, DOM-based XSS happens entirely in the browser when JavaScript code improperly handles user input. These vulnerabilities are particularly insidious because they can be invisible to server-side security tools and WAFs (Web Application Firewalls).
// Vulnerable code examples and their secure alternatives
// VULNERABLE: Direct innerHTML usage with user input
function displayUserComment(comment) {
// This allows arbitrary HTML and JavaScript injection
document.getElementById('comments').innerHTML = comment;
}
// SECURE: Using textContent for plain text
function displayUserCommentSecure(comment) {
document.getElementById('comments').textContent = comment;
}
// VULNERABLE: Using document.write with user input
function showWelcomeMessage() {
// User input from URL parameter
const name = new URLSearchParams(window.location.search).get('name');
document.write('Welcome, ' + name + '!'); // XSS vulnerability
}
// SECURE: Using DOM methods with proper encoding
function showWelcomeMessageSecure() {
const name = new URLSearchParams(window.location.search).get('name');
const welcomeDiv = document.createElement('div');
welcomeDiv.textContent = `Welcome, ${name}!`;
document.body.appendChild(welcomeDiv);
}
// VULNERABLE: jQuery html() with user input
function updateProfilejQuery(userBio) {
$('#user-bio').html(userBio); // XSS vulnerability
}
// SECURE: jQuery text() or proper sanitization
function updateProfilejQuerySecure(userBio) {
// For plain text
$('#user-bio').text(userBio);
// If HTML is needed, sanitize first
const sanitized = DOMPurify.sanitize(userBio, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br'],
ALLOWED_ATTR: []
});
$('#user-bio').html(sanitized);
}
// VULNERABLE: eval() and Function constructor
function calculateFormula(formula) {
// Never use eval with user input!
return eval(formula);
}
// SECURE: Parse and validate expressions safely
function calculateFormulaSecure(formula) {
// Use a proper expression parser library
const parser = new ExpressionParser();
// Whitelist allowed operations
parser.setAllowedOperations(['+', '-', '*', '/', '(', ')']);
parser.setAllowedVariables(['x', 'y', 'z']);
try {
return parser.evaluate(formula);
} catch (e) {
throw new Error('Invalid formula');
}
}