root@thehacksparrow:~/writeups$ SYSTEM ONLINE
root@sparrow:~/writeups$ cat vulnerability-pattern-xss.md
// bug-bounty

XSS

23 Jul 2026 · 3 min read

What it is

Stored XSS happens when you can save HTML/JavaScript into the application and it executes for anyone who later views that content — not just for you.

<img src=x onerror=alert(document.domain)>
saved as a project name, firing whenever someone else opens that project, is the classic shape of it.

Why it matters

It's worse than reflected XSS because it's persistent, hits other users (sometimes admins), can fire repeatedly, and — this is the part people miss — the payload is bound to the resource, not the attacker's account. Revoking the attacker's access doesn't remove the payload.

Where to look

  • Name / title / description / comment / bio fields
  • Company, job title, tags, filenames, project/campaign/template/workflow names
  • Especially in SaaS apps with collaboration, invites, shared workspaces, or resource duplication

How I test it

  1. List every field you can write to.
  2. Confirm HTML actually renders with a harmless probe like
    <b>test</b>
    .
  3. Try a non-destructive payload, and variants for different contexts: inside an attribute (
    "><img src=x onerror=alert(1)>
    ), inside a JS string (
    '-alert(1)-'
    ), or after a broken tag.
  4. Save, then test persistence: reload, log out and back in, open the resource from a different account, share it, duplicate/export/import it, check notifications and any emails it triggers.
  5. Check every view the field surfaces in — detail page, list, search, admin panel, preview, edit modal, history. A field sanitized in one view is often raw in another.

Hunting checklist

  • Mapped every writable field
  • Confirmed HTML rendering with a harmless probe
  • Tried a basic payload and an attribute-breaking variant
  • Reloaded and re-opened from a different account
  • Tried duplicate/export/import flows
  • Checked if the payload survives revoking the attacker's access
  • Checked innerHTML / dangerouslySetInnerHTML / v-html usage if source is visible

Evidence to collect

  • Vulnerable field
  • Payload used
  • Where it's stored
  • Where it fires
  • Attacker account
  • Victim account
  • Proof it runs in the victim's session
  • Proof of persistence across reload/duplicate/revoke

Recommended fix

  • Escape HTML on output
  • Sanitize input if HTML is intentionally allowed
  • Use
    textContent
    instead of
    innerHTML
  • Strong CSP
  • Validate on both frontend and backend
  • Re-sanitize on duplicate/export/import, not just on first save