Understanding the Different Types of XSS Attacks
What is XSS?
Cross-Site Scripting (XSS) is a security vulnerability that allows an attacker to inject malicious code, typically JavaScript, into a web page. When that code is executed in another user's browser, the attacker may be able to:
- Steal cookies or authentication tokens
- Read sensitive information
- Modify the page content
- Perform actions on behalf of the user
Most XSS vulnerabilities happen because applications don't safely handle user input.
The Three Main Types of XSS
- Stored XSS
- Reflected XSS
- DOM-Based XSS
1. Stored XSS
This is generally considered the most dangerous type of XSS. It occurs when malicious user input is stored in the database and later displayed to other users without proper sanitization or output encoding.
Common places where this happens include:
- Comments
- Product reviews
- Forum posts
- User profiles
Imagine an attacker submits the following comment:
<script>
// malicious JavaScript
</script>
If the application stores and renders that content without sanitizing it, every user who visits the page will execute the attacker's script. That's why it's called "stored XSS"; the payload is permanently stored on the server.
Impact
- Large-scale attacks affecting many users
- Session hijacking
- Account compromise
- Data theft
How to prevent it
- Validate and sanitize user input.
- Apply proper output encoding before rendering content.
- Use trusted sanitization libraries such as DOMPurify when rendering HTML.
- Enable Content Security Policy (CSP) as an additional defense layer.
2. Reflected XSS
Unlike Stored XSS, the malicious payload is not stored anywhere. Instead, it is reflected back to the user immediately through request data such as:
- Search inputs
- Query parameters
- URL fragments
A common attack looks like this:
- The attacker crafts a malicious URL.
- The victim clicks the link.
- The application reflects the input back into the page without escaping it.
- The browser executes the injected JavaScript.
Because the payload only exists in that request, the victim must interact with the malicious link for the attack to work.
Impact
- Cookie or token theft
- Session hijacking
- Redirecting users to phishing websites
- Executing actions on behalf of the victim
How to prevent it
- Validate incoming input.
- Always apply proper output encoding.
- Never render raw user input directly into HTML.
- Enable Content Security Policy (CSP).
3. DOM-Based XSS
This type is especially important for frontend developers because the vulnerability exists entirely inside the browser. The server may never be involved. It happens when JavaScript reads data from an untrusted source and writes it directly into the DOM without proper sanitization.
Common unsafe APIs include:
innerHTMLouterHTMLinsertAdjacentHTMLdocument.write()
If you're using React, you're already safer because React automatically escapes text by default. However, that protection disappears when using APIs like:
dangerouslySetInnerHTML
If the HTML you're rendering comes from an untrusted source, you can easily introduce a DOM XSS vulnerability.
Impact
- Data theft
- Page manipulation
- Executing arbitrary JavaScript
- Session hijacking
How to prevent it
- Avoid using
innerHTMLwhenever possible. - Avoid
dangerouslySetInnerHTMLwith untrusted content. - Sanitize HTML before rendering it.
- Review dangerous DOM sinks in your application.
The Golden Rule
Never trust user input. Whether the data comes from a form, a URL, an API, or even your own database, treat it as untrusted until you've validated, sanitized, and safely rendered it.
Defense against XSS isn't a single technique; it's a combination of secure coding practices, proper output encoding, sanitization, and browser protections like CSP.
This is the second post in my Frontend Security series. In the previous post, we explored Content Security Policy (CSP) and how it helps mitigate XSS attacks. If you'd like to check it out: https://dev.to/aymaneldawy/what-is-content-security-policy-csp-p6p
Comments
No comments yet. Start the discussion.