๐Ÿ”ต Stored XSS Lab

localStorage-Based Persistent Vulnerability

โš ๏ธ FOR EDUCATIONAL PURPOSES ONLY - DO NOT USE ON REAL SYSTEMS

๐Ÿ“š What is Stored XSS?

Stored Cross-Site Scripting (Persistent XSS) occurs when malicious input is stored (in a database, localStorage, file, etc.) and later displayed to users without proper sanitization. This is considered the most dangerous type of XSS because:

๐Ÿงช Comment System (Vulnerable)

๐Ÿ’ฌ Comments:

๐Ÿ’ก Try These Payloads

Post these as comments to see the vulnerability in action:

<img src=x onerror=alert('Stored XSS')>
<script>alert('This XSS persists!')</script>
<img src=x onerror="alert('Executed on every page load!')">
<h1 style="color: red;">DEFACED!</h1>

Notice: These payloads will be stored in localStorage and execute every time the page loads, demonstrating persistence!

๐Ÿ” Understanding the Vulnerability

Vulnerable Code:

// โŒ VULNERABLE: Storing and displaying user input with innerHTML
function postComment() {
  const comment = document.getElementById('input').value;
  
  // Store in localStorage (or database in real app)
  let comments = JSON.parse(localStorage.getItem('comments') || '[]');
  comments.push({text: comment, date: new Date()});
  localStorage.setItem('comments', JSON.stringify(comments));
  
  // Display using innerHTML - DANGEROUS!
  displayElement.innerHTML = comment;
}

The problem: User input is stored without sanitization and displayed using innerHTML, allowing malicious scripts to persist and execute for all users.

Secure Code:

// โœ… SECURE: Sanitize before storing and use textContent
function postComment() {
  const comment = document.getElementById('input').value;
  
  // Sanitize input before storing
  const sanitized = DOMPurify.sanitize(comment);
  
  // Or escape HTML
  const escaped = escapeHtml(comment);
  
  // Store sanitized version
  localStorage.setItem('comments', JSON.stringify([escaped]));
  
  // Display using textContent
  displayElement.textContent = escaped;
}

โš ๏ธ Real-World Impact

๐ŸŽฏ Common Attack Vectors

๐Ÿ”’ Prevention Techniques

๐Ÿงช Lab Details

This lab uses localStorage to simulate a database. In a real application, comments would be stored in a backend database. The vulnerability and prevention techniques are the same - never trust stored data and always sanitize/encode when displaying.

Try this: Post a malicious comment, then reload the page. Notice how the XSS payload executes again! This demonstrates the persistent nature of Stored XSS.