Vulnerability

Cross-Site Scripting (XSS)
detect, understand, remediate

XSS allows attackers to inject malicious scripts into web pages viewed by other users, enabling session hijacking, credential theft, and defacement.

No credit card required. Free plan available forever.

Severity

High

CWE ID

CWE-79

OWASP Top 10

A03:2021 – Injection

CVSS 3.1 Score

7.6

What is cross-site scripting (XSS)?

Cross-site scripting (XSS) is a client-side code injection vulnerability that occurs when an application includes untrusted data in its web pages without proper validation or encoding. An attacker can inject malicious JavaScript that executes in the context of a victim's browser session, giving them access to cookies, session tokens, and any data the user can see or do on the page.

There are three primary variants. Reflected XSS occurs when user input is immediately returned in the response, typically via a URL parameter that is rendered without encoding. Stored XSS is more dangerous: the malicious payload is persisted (in a database, comment field, or profile) and served to every user who views the affected page. DOM-based XSS happens entirely in the browser when client-side JavaScript processes untrusted data and writes it into the DOM without sanitisation.

XSS enables session hijacking, credential theft, phishing overlays, keylogging, and website defacement. Because the malicious script runs with the same privileges as the legitimate application, victims have no way to distinguish the attack from normal site behaviour. XSS remains one of the most common web application vulnerabilities and is a primary target in every penetration test.

How it works

1

Find unencoded output

Attacker identifies a location where user-supplied input is reflected or rendered in the page without proper output encoding.

2

Inject JavaScript payload

A crafted payload is submitted (such as a script tag, event handler attribute, or JavaScript URI) designed to execute in the victim's browser.

3

Victim triggers execution

The victim visits the page containing stored XSS, or clicks a link containing reflected XSS. The browser parses the injected script as legitimate code.

4

Script executes in context

The malicious JavaScript runs with full access to the page, stealing session cookies, redirecting the user, injecting phishing forms, or exfiltrating data.

Common causes

Missing output encoding

Rendering user input in HTML, JavaScript, CSS, or URL contexts without applying the correct encoding for that context.

Use of innerHTML and dangerouslySetInnerHTML

Directly inserting user-controlled strings into the DOM using unsafe APIs that parse HTML instead of treating it as text.

User input in script contexts

Embedding user data inside inline script blocks, event handler attributes, or JavaScript template literals without escaping.

Absence of Content Security Policy

Without a CSP header, browsers have no restrictions on inline scripts or external script sources, making XSS exploitation trivial.

How to detect it

Automated detection

  • SecPortal's authenticated scanner tests for reflected, stored, and DOM-based XSS across all discovered input points and parameters
  • SecPortal's code scanner identifies unsafe rendering patterns such as innerHTML usage, template injection, and missing encoding functions
  • Domain scanning checks for missing Content-Security-Policy headers that would mitigate XSS impact

Manual testing

  • Inject script tags, event handlers (onerror, onload, onfocus), and JavaScript URIs into every input field and URL parameter
  • Test different encoding contexts: HTML body, attribute values, JavaScript strings, CSS values, and URL parameters each require different payloads
  • Check stored inputs (comments, profiles, file names) by injecting payloads and verifying whether they execute when other users view the content

How to fix it

Apply context-appropriate output encoding

Encode all user-controlled data before rendering. Use HTML entity encoding for HTML body, JavaScript escaping for script contexts, URL encoding for URLs, and CSS escaping for style contexts.

Implement a strict Content Security Policy

Deploy a CSP header that disables inline scripts (no unsafe-inline), restricts script sources to trusted origins, and uses nonces or hashes for any necessary inline scripts.

Use HTML sanitisation libraries

When rich text input is required, use a proven sanitisation library (e.g. DOMPurify) that strips dangerous elements and attributes while preserving safe formatting.

Set HttpOnly and Secure cookie flags

Mark session cookies as HttpOnly to prevent JavaScript access, and Secure to ensure they are only sent over HTTPS. This limits the impact of XSS by protecting session tokens.

Avoid innerHTML and unsafe DOM APIs

Use textContent or innerText instead of innerHTML. In React, avoid dangerouslySetInnerHTML. In other frameworks, use the built-in template escaping rather than raw HTML insertion.

Compliance impact

Detect XSS automatically

SecPortal tests for reflected, stored, and DOM-based XSS across all authenticated endpoints. Start scanning for free.

No credit card required. Free plan available forever.