Skip to main content

Cross-Site Scripting (XSS)

XSS occurs when applications include untrusted data in web pages without proper encoding, allowing attackers to execute malicious scripts in victims' browsers.

High CWE-79 A03:2021 Injection
Affects: JavaScriptTypeScriptPHPJavaC#PythonRuby

What is Cross-Site Scripting?

Cross-Site Scripting (XSS) is a vulnerability that allows attackers to inject malicious scripts into web pages viewed by other users. When a victim visits the affected page, the attacker’s script executes in their browser with the same permissions as the legitimate application.

There are three main types:

  • Reflected XSS — Malicious input is immediately reflected back in the response (e.g., search results, error messages)
  • Stored XSS — Malicious input is stored on the server (e.g., in a database) and displayed to other users later
  • DOM-based XSS — The vulnerability exists in client-side JavaScript that unsafely modifies the DOM using user input

Why it matters

XSS enables attackers to:

  • Steal session tokens — Hijack user accounts by capturing cookies
  • Perform actions as the victim — Submit forms, change passwords, make purchases
  • Redirect users — Send victims to phishing sites or malicious downloads
  • Deface the application — Modify visible page content
  • Capture keystrokes — Record everything the user types, including passwords

Stored XSS is particularly dangerous because it affects every user who views the compromised content, potentially impacting thousands of users from a single injection.

Vulnerable code examples

JavaScript / Express

// VULNERABLE: User input reflected without encoding
app.get('/search', (req, res) => {
  const query = req.query.q;
  res.send(`<h1>Results for: ${query}</h1>`);
});

PHP

<!-- VULNERABLE: Direct output without encoding -->
<div>Welcome, <?php echo $_GET['name']; ?></div>

C# / ASP.NET MVC

// VULNERABLE: Using Html.Raw with user input
@Html.Raw(ViewBag.UserComment)

DOM-based (Client-side JavaScript)

// VULNERABLE: Writing URL hash directly to DOM
document.getElementById('output').innerHTML = location.hash.substring(1);

Secure code examples

JavaScript / Express

// SECURE: Use a template engine that auto-escapes, or encode manually
import escapeHtml from 'escape-html';
app.get('/search', (req, res) => {
  const query = escapeHtml(req.query.q);
  res.send(`<h1>Results for: ${query}</h1>`);
});

PHP

<!-- SECURE: htmlspecialchars with proper flags -->
<div>Welcome, <?php echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8'); ?></div>

React (auto-escapes by default)

// SECURE: React auto-escapes expressions in JSX
function SearchResults({ query }) {
  return <h1>Results for: {query}</h1>;
}

// DANGEROUS: dangerouslySetInnerHTML bypasses this protection
// Never use with user input

C# / ASP.NET Razor

// SECURE: Razor auto-encodes @ expressions
<div>@Model.UserComment</div>

// DANGEROUS: @Html.Raw() skips encoding — avoid with user input

What Offensive360 detects

Our scanner identifies XSS by tracing user-controlled data from input sources to output sinks:

  • Reflected XSS — HTTP parameters, headers, or cookies rendered in HTML responses without encoding
  • Stored XSS — User input stored in databases and later rendered without encoding
  • DOM-based XSS — Client-side JavaScript using innerHTML, document.write, or eval with untrusted data
  • Template injection — Unsafe use of template engines that bypass auto-escaping
  • Framework bypasses — Use of dangerouslySetInnerHTML (React), Html.Raw (ASP.NET), |safe (Django), raw (Rails)

Remediation guidance

  1. Use contextual output encoding — Encode data for the specific context: HTML body, HTML attribute, JavaScript, CSS, or URL
  2. Use frameworks that auto-escape — React, Angular, Vue, Razor, and modern template engines escape by default
  3. Set Content-Security-Policy headers — CSP restricts which scripts can execute, limiting XSS impact
  4. Set HttpOnly flag on session cookies — Prevents JavaScript from accessing session tokens
  5. Validate and sanitize rich text — If you must accept HTML input, use a proven sanitizer library like DOMPurify

References

Author: Offensive360 Security Research
Last reviewed: March 1, 2026

Detect Cross-Site Scripting (XSS) in your code

Run Offensive360 SAST against your codebase to find this and hundreds of other vulnerabilities.