You can build a beautiful web application, use a modern framework, follow a clean architecture — and still leave a tiny opening for an XSS attack.
Sometimes, that opening is nothing more than a search box, comment field, profile form, or URL parameter.
That's what makes Cross-Site Scripting (XSS) worth understanding.
What actually happens during an XSS attack?
At its simplest, XSS happens when an application takes untrusted input and eventually causes the browser to interpret that input as executable code.
The dangerous part isn't simply that someone entered malicious JavaScript.
The real problem is this:
The application trusted something it shouldn't have trusted.
A simplified attack flow looks like this:
Attacker
↓
Untrusted Input
↓
Vulnerable Application
↓
Browser
↓
Malicious Script Executes
For example, imagine an application accepting a comment and rendering it directly into a webpage.
If the application doesn't handle the input safely, something as simple as:
<script>alert('XSS')</script>
could be interpreted as code instead of ordinary text.
A real attacker would obviously have a more useful objective than displaying an alert.
Depending on the vulnerability and application architecture, XSS can be used to manipulate page content, capture user input, perform actions as a victim, facilitate phishing, or compromise sessions.
The 3 types developers should know
1. Stored XSS -
Think:
- 1. Comments
- 2. User profiles
- 3. Forum posts
- 4. Chat messages
- 5. Database-backed content
A victim later loads the affected page and the malicious content executes in their browser.
This is particularly dangerous because the attacker doesn't necessarily need to target every victim individually.
2. Reflected XSS -
Here, the malicious input is reflected immediately by the application.
A common example is a search page that displays the user's search term without safely encoding it.
The attacker can construct a malicious URL and attempt to convince someone to open it.
3. DOM-based XSS -
This one happens primarily on the client side.
The server may never receive the malicious payload.
Instead, JavaScript takes untrusted data from sources such as a URL, hash fragment, cookie, or local storage and inserts it into the DOM in an unsafe way.
This is particularly relevant to modern JavaScript-heavy applications and SPAs.
So how do you actually prevent XSS?
The answer isn't simply:
Sanitize everything.
Good XSS prevention is a combination of several practices.
1. Validate input
Don't blindly trust user-controlled data.
Validation should happen according to what the application actually expects.
2. Encode output
This is one of the most important concepts.
The application should encode data according to the context where it will be rendered.
HTML, JavaScript, CSS and URL contexts don't all behave the same way.
3. Be careful with DOM manipulation
Developers should be especially cautious when handling APIs such as:
innerHTML
outerHTML
document.write()
When you simply need to display text, safer approaches such as textContent are often preferable.
4. Use Content Security Policy
A properly configured Content Security Policy (CSP) provides another defensive layer by controlling which scripts and other resources the browser is allowed to execute or load.
It shouldn't replace secure coding, but it can reduce the impact of certain vulnerabilities.
5. Protect authentication cookies
Using appropriate cookie attributes such as HttpOnly and Secure can reduce the impact of some attacks involving session cookies.
Again, this isn't a replacement for fixing XSS itself.
6. Don't assume your framework makes you invulnerable
Modern frameworks such as React, Angular and Vue provide important protections by default.
But developers can still introduce vulnerabilities through unsafe APIs, third-party libraries, custom rendering logic, or bypass mechanisms.
Framework security features are a safety layer — not permission to stop thinking about input and output handling.
XSS is ultimately an application architecture problem
This is the part that often gets overlooked.
XSS isn't just something a developer fixes at the end of a project.
It can be introduced through:
- Frontend components
- Backend APIs
- Database content
- Authentication flows
- Third-party packages
- Rich-text editors
- User-generated content
- DOM manipulation
That's why security needs to be considered during the design and development process rather than after the application is already in production.
If you're building a new application, the security model should be part of the architecture from day one.
For businesses developing complex applications, this becomes even more important when the system includes customer accounts, dashboards, CRMs, payments, APIs or sensitive business data.
That's one of the reasons we approach custom software development as an engineering problem rather than simply building features.
Want the complete XSS breakdown?
I published a more detailed guide covering the attack flow, Stored vs Reflected vs DOM-based XSS, real-world incidents, prevention techniques and developer FAQs:
XSS Attack Explained: Types, Examples & Prevention Guide
If you're developing or maintaining a web application, it's worth understanding how a seemingly harmless input field can become a security boundary.

Top comments (0)