๐Ÿ” 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.

None

๐Ÿ’ฅ 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 onerror event 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 HttpOnly and Secure flags

๐Ÿ“ข 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.