XSS Security Lab

Stored XSS Vulnerability Demonstration

Local Testing Environment

🔴 VULNERABLE - Stored XSS

Comment System with Stored XSS

This lab demonstrates a Stored XSS vulnerability in a comment system. User comments are saved to localStorage and displayed using innerHTML without sanitization, allowing JavaScript payloads to execute when comments are rendered.
Cookie Status: Checking cookies...
Cookies set: None
Storage Info: Comments stored in localStorage - persist after page reload and browser restart (0 comments stored)

Comments:

No comments yet. Be the first to comment!

✅ Solution & Security Fix

Why Cookie Theft Works Here:

This lab sets demo cookies on page load. When the XSS payload executes alert(document.cookie), it displays all non-HttpOnly cookies. This lab also demonstrates how XSS can inject a username into the page when untrusted input is inserted without proper sanitization.

Vulnerable Code (Current Implementation):

// DANGER: Using innerHTML with unsanitized user input
function displayComments() {
    const comments = JSON.parse(localStorage.getItem('comments')) || [];
    const container = document.getElementById('commentsContainer');
    
    let html = '';
    comments.forEach(comment => {
        // VULNERABLE: Direct HTML injection
        html += `<div>${comment.text}</div>`;
    });
    
    container.innerHTML = html; // XSS HERE!
}

Secure Implementation (Fix):

// FIX 1: Use textContent (Recommended)
function displayCommentsSecure() {
    const comments = JSON.parse(localStorage.getItem('comments')) || [];
    const container = document.getElementById('commentsContainer');
    container.innerHTML = '';
    
    comments.forEach(comment => {
        const div = document.createElement('div');
        div.textContent = comment.text; // Safe!
        container.appendChild(div);
    });
}

// FIX 2: HTML Entity Encoding
function escapeHtml(unsafe) {
    return unsafe
        .replace(/&/g, "&")
        .replace(//g, ">")
        .replace(/"/g, """)
        .replace(/'/g, "'");
}

Cookie Protection:

  • Set HttpOnly flag to prevent JavaScript access
  • Use Secure flag for HTTPS-only transmission
  • Set SameSite=Strict to prevent CSRF
  • Implement Content-Security-Policy headers