SalakCode SalakCode
Security

XSS Prevention

Protect your application from cross-site scripting attacks

Intermediate
security xss sanitization csp

Definition

Cross-Site Scripting (XSS) is a security vulnerability that allows attackers to inject malicious scripts into web pages viewed by other users. XSS attacks can steal session cookies, impersonate users, or perform unwanted actions on their behalf.

Types of XSS

Reflected XSS

// Vulnerable code
const searchTerm = new URLSearchParams(window.location.search).get('q');
document.write(`<h1>Results for: ${searchTerm}</h1>`);

// Attack URL: ?q=<script>stealCookies()</script>

Stored XSS

// Vulnerable comment system
function displayComment(comment) {
  // User input saved to database and displayed to all users
  document.getElementById('comments').innerHTML += comment.text;
}

// Attacker posts: <img src=x onerror="stealData()">

DOM-based XSS

// Vulnerable hash-based routing
window.addEventListener('hashchange', () => {
  const hash = location.hash.slice(1);
  document.getElementById('content').innerHTML = hash; // Dangerous!
});

// Attack: #<img src=x onerror=alert(document.cookie)>

Prevention Techniques

1. Output Encoding

// HTML encoding
function escapeHtml(text) {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
}

// Or use a library like DOMPurify
import DOMPurify from 'dompurify';

// Safe rendering
const userInput = '<script>alert("xss")</script>';
const safeHtml = escapeHtml(userInput); // &lt;script&gt;...

document.getElementById('output').textContent = userInput; // Safe
document.getElementById('output').innerHTML = safeHtml;     // Safe

2. Content Security Policy (CSP)

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self' 'nonce-abc123';">

<script nonce="abc123">
  // This script will execute
</script>

<script>
  // This inline script will be blocked
</script>

3. React/Vue/Angular Auto-Escaping

// React automatically escapes
function UserProfile({ user }) {
  return <div>{user.name}</div>; // Safe - auto-escaped
}

// Dangerous - explicit HTML
function Dangerous({ html }) {
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
}

// Safe with sanitization
import DOMPurify from 'dompurify';

function SafeHtml({ html }) {
  const clean = DOMPurify.sanitize(html);
  return <div dangerouslySetInnerHTML={{ __html: clean }} />;
}

4. Input Validation

// Whitelist approach
function validateUsername(username) {
  const regex = /^[a-zA-Z0-9_]{3,20}$/;
  return regex.test(username);
}

// Sanitize URLs
function sanitizeUrl(url) {
  const allowedProtocols = ['http:', 'https:', 'mailto:'];
  try {
    const parsed = new URL(url);
    return allowedProtocols.includes(parsed.protocol) ? url : '#';
  } catch {
    return '#';
  }
}

5. HTTP-only Cookies

// Server-side: Set cookies as HTTP-only
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict

// JavaScript cannot access HTTP-only cookies
document.cookie; // sessionId is not visible

Best Practices

Avoid Dangerous APIs

// Dangerous - avoid these
element.innerHTML = userInput;
document.write(userInput);
eval(userInput);
setTimeout(userInput);
setInterval(userInput);
new Function(userInput);
location.href = userInput; // javascript: protocol

// Safe alternatives
element.textContent = userInput;
element.innerText = userInput;
document.createTextNode(userInput);

URL Validation

function isValidRedirect(url) {
  try {
    const parsed = new URL(url, window.location.origin);
    // Only allow same-origin redirects
    return parsed.origin === window.location.origin;
  } catch {
    return false;
  }
}

// Usage
const returnUrl = new URLSearchParams(location.search).get('return');
if (isValidRedirect(returnUrl)) {
  location.href = returnUrl;
}
Key Takeaway

Prevent XSS by encoding output, validating input, implementing CSP, and avoiding dangerous APIs like innerHTML with user data. Modern frameworks provide automatic escaping, but stay vigilant with dangerouslySetInnerHTML. Use HTTP-only cookies to protect session data even if XSS occurs.

Resources

Related Topics