๐ Introduction
Cross-Site Scripting (XSS) is one of the most common web vulnerabilities that allows attackers to inject malicious scripts into web pages viewed by other users.
There are three main types:
- Reflected XSS
- Stored XSS
- DOM-based XSS
In this write-up, I'll walk through a Stored XSS vulnerability I discovered in a blog posting feature during testing in a controlled environment.
๐ฏ Target Overview (Anonymized)
The application includes a user profile system where users can:
- Modify profile settings
- Access a blog section
- Create and publish posts
The vulnerable endpoint looked like this (anonymized):
๐ Vulnerability Discovery
While testing input fields inside the blog post functionality, I noticed that user-supplied content was rendered back into the page without proper sanitization or encoding.
To test this, I injected a simple HTML payload:
<img src=x onerror=alert(1)>The application accepted and rendered the input, which indicated lack of input validation.

๐ฅ Proof of Concept (PoC)
Next, I escalated the test by injecting a JavaScript event handler:
<img src=x onerror=alert(document.domain)>๐ What happens here:
- The browser fails to load
src=x - The
onerrorevent is triggered - JavaScript executes inside the victim's browser
When the blog post was viewed, the payload executed successfully, confirming the vulnerability.
๐ง Vulnerability Classification
Although initially it might appear as reflected behavior, this is actually:
โก๏ธ Stored XSS (Persistent XSS)
Because:
- The payload is saved in the database
- It executes every time the page is loaded
โ ๏ธ Impact Analysis
This vulnerability can lead to serious security risks:
- Session Hijacking (if cookies are accessible)
- Account Takeover (especially if an admin views the page)
- Phishing Attacks (injecting fake UI elements)
- Privilege Escalation
- Malicious Script Execution in user browser
๐ Root Cause
The issue exists due to:
- Lack of input sanitization
- No output encoding before rendering
- HTML content being directly injected into the DOM
- Dangerous attributes (
onerror) not filtered
๐ก๏ธ Mitigation Strategies
To fix this vulnerability, the following measures should be implemented:
1. Output Encoding
- Encode special characters (
<,>,",') before rendering
2. Input Sanitization
- Remove or sanitize dangerous HTML tags and attributes
3. Use Security Libraries
- Libraries like DOMPurify can sanitize user input safely
4. Implement Content Security Policy (CSP)
- Restrict execution of inline scripts
- Prevent exploitation even if injection occurs
5. Secure Cookies
- Use
HttpOnlyandSecureflags
๐ข Responsible Disclosure
- The vulnerability was reported privately to the website owner
- Adequate time was given for remediation
- This article is published only after ensuring no harm to users
โ๏ธ Conclusion
This case highlights how small oversights in input handling can lead to critical vulnerabilities like Stored XSS.
Proper validation, encoding, and security controls are essential to protect modern web applications.
๐งช Key Takeaway
Never trust user input โ always validate, sanitize, and encode before rendering.