# Stored XSS in topics because of whitelisted_generic engine vulnerability

Discourse's whitelisted_generic onebox engine decoded OpenGraph values then injected them into raw HTML, enabling stored XSS via a crafted topic URL.

- Payout: hidden
- Severity: high
- Program: Discourse
- Found by: skavans
- Disclosed: 2017-01-20
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/197902
- Library page: https://bugbountylibrary.com/r/h1%3A197902
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:high tech:ruby technique:incomplete-fix technique:source-review vuln:xss

**Target:** onebox engine (whitelisted_generic_onebox.rb) rendering OpenGraph metadata in forum topics
**Root cause:** The whitelisted_generic onebox engine HTML-decodes OpenGraph variable values (lines 202/207) and then injects the decoded values into raw HTML (lines 284/289), so escaping applied earlier is undone before rendering.
**Steps:**
1. Post a URL in a topic: `http://89.223.28.48/og_image.html?uncache1234`
2. Save the post
3. The onebox fetches OpenGraph data; the engine decodes the values and injects them into raw HTML, firing the stored XSS
**How found:** Noticed that although OpenGraph data was now escaped, the whitelisted_generic engine decodes variable values back at specific lines and then injects them into raw HTML, undoing the escaping.
**Exploitation:** Attacker hosts a page whose OpenGraph metadata contains HTML-encoded payload; when a user posts the link, Discourse's onebox decodes the values and injects them unescaped into the rendered post, executing script for viewers.
**Insight:** When a fix adds escaping at one layer, check downstream code for decode/unescape calls that reverse it before raw HTML injection — double-decoding defeats the sanitizer.

