# Stored XSS on https://www.algolia.com/realtime-search-demo/*

Algolia UI demo generator failed to escape attribute names, allowing stored XSS via crafted input name that executes on shared demo pages.

- Payout: hidden
- Severity: high
- Program: Algolia
- Found by: stefanovettorazzi
- Disclosed: 2016-02-03
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/98012
- Library page: https://bugbountylibrary.com/r/h1%3A98012
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:high tech:rest technique:source-review vuln:xss

**Target:** UI demo generator at /realtime-search-demo/*
**Root cause:** Attribute names from the demo generator were interpolated into JavaScript on the demo page without escaping; Cloudflare WAF only filtered values, not parameter names.
**Steps:**
1. Log in and open https://www.algolia.com/explorer, click GENERATE A UI DEMO.
2. Enter any Title, click NEXT.
3. Inspect the Primary attribute input and change its name to `engine[primary_attribute]['+document.write`${unescape`%3cimg%20src%3dx%20onerror%3dalert%28document.domain%29%3e`}`+']`.
4. Click NEXT, then GENERATE UI & SHARE.
5. `alert(document.domain)` fires; copy the resulting demo URL and open it as another user to confirm stored XSS.
**How found:** Noticed attribute values were unescaped in generated JS; Cloudflare blocked payloads in values but was more permissive with payloads in parameter names, so moved the payload into the input name.
**Exploitation:** Attacker crafts a demo with a malicious attribute name, generates a shareable realtime-search-demo URL, and sends it to victims; visiting the link executes attacker JavaScript in the algolia.com origin.
**Insight:** When a WAF filters parameter values, try injecting into parameter names or array keys that get reflected into JS; template-literal `${unescape`...`}` bypasses naive escaping.

