Home / Knowledge hub / XSS
Knowledge hub
XSS
An attacker's script running in your pages, in your customers' sessions.
What it means
XSS stands for cross-site scripting. An attacker gets script of their own choosing to run inside your pages, in your customers' browsers, in their signed-in sessions.
It happens when a value a user supplied lands in a page and nothing escapes it first. A comment, a name, a search term echoed back, a value pulled from a URL. The browser cannot tell your markup from theirs.
Why it matters
Script running in your page does whatever the person using it could do. Read what is on screen. Submit a form as them. Change their email address. Take the session token quietly and spend it later.
From the customer's side, all of it happens on your domain, in your interface, behind your certificate. Nothing gives them a reason to notice, and nothing tells them they did anything wrong. A content security policy limits the damage, but the escaping still has to be right.
How it shows up
The stored kind hurts most. Your application stores the value and serves it to everyone who opens that record, including staff viewing it in an admin screen. Reflected versions need a link and a click. Stored ones only need somebody to look. Both deserve the same fix, and only the reach differs.
Modern templates escape by default, so the flaw usually shows up where somebody bypassed that. Raw HTML inserted on purpose. A value dropped into a script block. Markup assembled by hand. Check the outputs that are not pages, too. A name rendered into a PDF, an email template or an exported spreadsheet carries the same problem into a different reader.
Questions people ask
XSS, answered
Is XSS still a real problem, or is it a solved one?
Still real. Frameworks removed the easy version, so what remains is the awkward version: rich text editors, markdown renderers, content from a CMS, third-party widgets.
Those are exactly the places where somebody had to switch the escaping off to make a feature work.
Does React protect me from XSS?
Mostly, for values rendered between JSX braces. It does not cover everything.
The gaps are dangerouslySetInnerHTML, attributes that accept a URL where a javascript: value still runs, and anything injected outside React's control. The framework escapes text; it cannot guess your intent.
What is the difference between stored, reflected and DOM-based XSS?
Stored means your application keeps the value and serves it to whoever opens the record later. Reflected means it travels in the request and bounces straight back, so the attacker needs you to click a link.
DOM-based means the page's own JavaScript takes an attacker-controlled value and writes it into the document, without the server ever seeing the problem.
Is a content security policy enough on its own?
No. A good policy limits what injected script can do and can stop an attack becoming a disaster, which makes it well worth having.
It is a second layer. Policies get relaxed for an analytics tool or an embedded widget, and the escaping is what stops the injection in the first place.
Why does XSS matter if it only affects the user's own browser?
Because the browser it affects may be a member of your staff. Stored XSS in a support ticket runs when an administrator opens that ticket, in their session, with their permissions.
That is how a customer-supplied string turns into an administrative action.
Related
Terms that sit next to this one
Injection
Input that ends up running as a command instead of being read as text.
Input validation
Checking that what arrives is the shape and range you expected.
Content Security Policy
A header telling the browser which scripts a page may load.
Session hijacking
Stealing the token that tells your application a browser is logged in.
Untrusted input
Anything that arrived from outside your own code, and is therefore suspect.
Anywhere you render HTML by hand?
Cross-site scripting is one of the ten vulnerability classes Cyberlop tests, and findings arrive with a screenshot of the script running. Start with one application for $199.
Or start with a $199 pilot on one application: thirty days, success criteria agreed before day one, credited against the annual if you convert.