
Cross-Site Scripting, or XSS for short, is one of the oldest known web vulnerabilities—and yet we still find it regularly in modern applications. Since the early 2000s, it has continued to affect security researchers, developers, and bug bounty hunters alike. But why?
What is XSS?
XSS involves injecting JavaScript code into a website, where it is then executed in the victim’s browser. What makes it so dangerous is that the code runs with the same privileges as the legitimate website. This allows attackers to:
- steal cookies and session tokens
- manipulate user actions
- take over accounts
- modify content on behalf of the victim
- redirect victims to other websites.
In short, the victim’s browser executes the attacker’s code— opening the door to a wide range of attack scenarios.
Simple example
A blog with a comment form stores user comments and displays them again without filtering:
<!-- The comment is rendered directly -->
Benutzer schrieb: NAME
If an attacker enters the following value instead of their name:
alert('XSS!');
this script is executed every time the page is opened.
This is a classic stored XSS vulnerability.
Why does XSS never die?
Although XSS has been known for more than 20 years, it remains a recurring issue in penetration tests, bug bounty programs, and CVEs. There are many reasons:
- Complex input
Web applications process countless fields, forms, comments,
and search queries. Almost inevitably, an edge case is overlooked somewhere. Example: A search field permits input such as
">. If the result is inserted into the page without escaping, the result is reflected XSS. - Frameworks help—but not perfectly
Modern frameworks such as React, Angular, and Vue include
protective mechanisms. If they are used incorrectly, however,
vulnerabilities can still arise. Example: In React,
dangerouslySetInnerHTMLshould never be used without sanitizing the input first. Otherwise, JavaScript can be executed directly. - Legacy code
Many applications are based on old code that is never fully
modernized. Old vulnerabilities persist and reappear in new
contexts. Example: JSP or PHP applications from the 2000s that output
echo $_GET['q'];or<%= request.getParameter("q") %>without encoding. - New features Every new browser API or feature also creates new attack surfaces. Example: XSS through SVG files with embedded event handlers (``) or modern HTML5 attributes.
The conclusion: as long as dynamic websites exist, XSS will exist as well.
Real-world example: CVE-2024-47950 in TeamCity
An example from 2024 shows how real the problem remains. I found a vulnerability in JetBrains TeamCity, documented as CVE-2024-47950 (technical details are available here).
TeamCity is a widely used CI/CD tool that companies use for software builds and deployments.
The vulnerability was a stored XSS. This means that an attacker could inject JavaScript code that was stored permanently in the application. Whenever other users or administrators opened the affected page, the code was executed automatically.
Why is this dangerous?
- Persistence: The attack remains active—every user who visits the page is affected.
- High impact: XSS can have catastrophic consequences, particularly in an admin backend.
- Potential consequences: Session takeover, access to confidential data, and manipulation of entire build pipelines.
JetBrains fixed the vulnerability promptly, and it has been resolved for more than a year. I published the Proof of Concept in a separate blog post here.
This example makes one point clear: even modern, security-critical software is not immune to XSS.
What can we learn from this?
XSS demonstrates that IT security is not a problem that can be solved once and forgotten. We need to remain vigilant continuously. In practical terms, this means:
- validating input strictly
- escaping output correctly (HTML, JavaScript, CSS, URL – each according to its context!)
- implementing a Content Security Policy (CSP)
- understanding frameworks and using them securely
An example of correct escaping in PHP:
<?php echo htmlspecialchars($_GET['q'], ENT_QUOTES, 'UTF-8'); ?>
Most importantly: raising developer awareness. This is the only way to prevent old vulnerabilities from resurfacing repeatedly in new projects.
Conclusion
“XSS never dies” is more than just a saying. It is a reminder that web security is an ongoing process.
Those who understand XSS and take it seriously can prevent it successfully—but this vulnerability should never be underestimated.
Additional information
I created a YouTube clip about this topic:
For anyone who wants to learn more about XSS:
- Portswigger Academy (free)
- HTB Academy (paid)