Step-by-Step Guide
7 steps

How to Prevent XSS Attacks

Cross-Site Scripting (XSS) allows attackers to inject malicious scripts into your website. These scripts can steal user sessions, redirect to phishing sites, or modify page content. This guide covers every layer of defense against XSS attacks.

Find security issues automatically before attackers do.

Follow These Steps

1

Use framework auto-escaping

Modern frameworks like React, Vue, and Angular auto-escape output by default. Never bypass this.

Code Example
// React - SAFE (auto-escaped)
return <div>{userInput}</div>

// React - DANGEROUS (bypasses escaping)
return <div dangerouslySetInnerHTML={{ __html: userInput }} />

// Only use dangerouslySetInnerHTML with sanitized content:
import DOMPurify from 'dompurify'
return <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
2

Sanitize HTML if you must render user content

Use DOMPurify to strip malicious HTML while preserving safe formatting.

Code Example
import DOMPurify from 'dompurify'

// Allow only safe HTML tags
const clean = DOMPurify.sanitize(userInput, {
  ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br'],
  ALLOWED_ATTR: ['href', 'target'],
  ALLOW_DATA_ATTR: false
})
3

Implement Content Security Policy

CSP is the strongest defense against XSS. It prevents execution of injected scripts.

Code Example
// Add CSP header
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123'
4

Validate and sanitize input on the server

Never trust user input. Validate type, length, and format on the server.

Code Example
import { z } from 'zod'

const CommentSchema = z.object({
  text: z.string()
    .min(1)
    .max(5000)
    .transform(val => val.trim())
})
5

Use httpOnly cookies for session tokens

httpOnly cookies cannot be accessed by JavaScript, preventing session theft via XSS.

Code Example
res.cookie('session', token, {
  httpOnly: true,  // Cannot be read by JavaScript
  secure: true,    // Only sent over HTTPS
  sameSite: 'lax', // Prevents CSRF
  maxAge: 86400000 // 1 day
})
6

Escape data in different contexts

Different contexts require different encoding strategies.

Code Example
// HTML context (React handles this automatically)
<div>{userInput}</div>

// URL context
<a href={`/search?q=${encodeURIComponent(userInput)}`}>Search</a>

// JavaScript context (avoid inserting user data into scripts)
// DANGEROUS:
<script>var name = "{userInput}"</script>
// SAFE: Use data attributes instead
<div data-name={userInput} />
7

Scan for XSS vulnerabilities

Run VAS to detect XSS vulnerabilities including missing CSP headers and unsafe DOM manipulation patterns.

What You'll Achieve

Your application has multiple layers of XSS protection: framework auto-escaping, DOMPurify for user HTML, Content Security Policy, input validation, httpOnly cookies, and context-appropriate encoding.

Common Mistakes to Avoid

Mistake

Using dangerouslySetInnerHTML without DOMPurify

Fix

Always sanitize with DOMPurify before rendering user-provided HTML. Never trust user input, even from your own database.

Mistake

Thinking input validation alone prevents XSS

Fix

Input validation helps but is not sufficient. Output encoding (auto-escaping) is the primary defense. CSP provides the strongest protection.

Mistake

Disabling React auto-escaping for convenience

Fix

React auto-escapes by default. Never use dangerouslySetInnerHTML unless absolutely necessary, and always sanitize the content.

Frequently Asked Questions

Does React prevent XSS automatically?

React auto-escapes output in JSX expressions, which prevents most XSS. However, dangerouslySetInnerHTML, href attributes with javascript: URLs, and server-rendered content still require attention.

What is the difference between stored and reflected XSS?

Stored XSS persists in your database (e.g., a malicious comment). Reflected XSS comes from URL parameters (e.g., a crafted search link). Both are prevented by output encoding and CSP.

Is input validation enough to prevent XSS?

No. Input validation reduces attack surface but is not a complete defense. Output encoding (auto-escaping) and CSP are the primary defenses against XSS.

Ready to Secure Your App?

VAS automatically scans your deployed app for the security issues covered in this guide. Get actionable results in minutes.

Start Security Scan