What is XSS (Cross-Site Scripting)? Security Guide

Share

TL;DR

XSS (Cross-Site Scripting) is when attackers inject malicious JavaScript into your website that runs in other users' browsers. If your app displays user input without sanitizing it, attackers can steal session cookies, redirect users to phishing sites, or perform actions as the victim. Modern frameworks like React help prevent XSS by default, but you can still introduce vulnerabilities with dangerouslySetInnerHTML or unsanitized URLs.

The Simple Explanation

Imagine a comment section on a blog. A user types a comment, and it shows up on the page. Now imagine someone posts this "comment":

::prompt-box{title="Malicious "comment""}

::

If the site doesn't sanitize this input, the script runs in every visitor's browser. Their login cookies get sent to the attacker, who can now impersonate them.

Types of XSS

  • Stored XSS: Malicious script is saved to database, shown to all users (most dangerous)
  • Reflected XSS: Script is in URL, reflected back in page
  • DOM-based XSS: Client-side JS processes untrusted data

Why XSS Is Dangerous

XSS remains one of the top 10 most reported vulnerabilities. What attackers can do with XSS:

  • Steal sessions: Access document.cookie and hijack logged-in accounts
  • Keylogging: Capture everything the user types, including passwords
  • Phishing: Replace page content with fake login forms
  • Malware: Redirect users to sites that download malware
  • Defacement: Change what users see on your site

How Modern Frameworks Help

React, Vue, and Angular escape output by default. This is safe:

React: Safe by default

const Comment = ({ text }) => { return

{text}

; }; // Input: "" // Output: Displays as text, doesn't execute

The exception: dangerouslySetInnerHTML in React bypasses escaping. If you use it with unsanitized user input, you create an XSS vulnerability.

How to Prevent XSS

1. Use Framework Defaults

Let React, Vue, or Angular escape output. Avoid raw HTML insertion unless absolutely necessary.

2. Sanitize When You Must Render HTML

If you need to display HTML (like rich text from an editor), use DOMPurify:

Safe HTML rendering with DOMPurify

import DOMPurify from 'dompurify';

const SafeHTML = ({ html }) => { const clean = DOMPurify.sanitize(html); return <div dangerouslySetInnerHTML= />; };

3. Use Content Security Policy (CSP)

CSP headers tell browsers which scripts are allowed to run. Even if XSS gets injected, CSP can block it.

What is the difference between XSS and SQL injection?

SQL injection targets your database by injecting malicious SQL commands. XSS targets your users by injecting malicious JavaScript that runs in their browsers. SQL injection steals or modifies your data. XSS steals user sessions, credentials, or performs actions as the user.

Does React automatically prevent XSS?

React escapes values by default, which prevents most XSS. However, using dangerouslySetInnerHTML bypasses this protection. If you must render HTML, use a sanitization library like DOMPurify. Also, href attributes with javascript: URLs can still be exploited.

What is Content Security Policy (CSP)?

CSP is an HTTP header that tells browsers which sources of scripts are allowed to run. Even if an attacker injects a script, CSP can prevent it from executing by blocking inline scripts or scripts from untrusted domains. It is a powerful second layer of XSS defense.

Check for XSS

Scan your app for cross-site scripting vulnerabilities.

Start Free Scan
Security Glossary

What is XSS (Cross-Site Scripting)? Security Guide