# Stored XSS in Private Message component (BuddyPress)

BuddyPress private messages render HTML, so an authenticated user can send an iframe javascript: payload that executes stored XSS in the recipient's session, including admins.

- Payout: hidden
- Severity: critical
- Program: WordPress
- Found by: klmunday
- Disclosed: 2019-03-08
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/487081
- Library page: https://bugbountylibrary.com/r/h1%3A487081
- Tags: area:web domain:web impact:ato impact:privesc kind:bounty platform:hackerone sev:critical tech:php technique:chained vuln:xss

**Target:** BuddyPress private message compose/reply and inbox preview
**Root cause:** Private message content is stored and rendered as HTML without sanitizing dangerous elements/attributes, allowing iframe src=javascript: URIs to execute in the recipient's browser.
**Steps:**
1. Log in as any user with default permissions (private messaging enabled).
2. Open another user's profile and click private message (or reply to an existing thread).
3. Enter any subject and message body `Test<iframe src=javascript:alert(1) width=0 height=0 style=display:none;></iframe>`.
4. Send the message; the XSS triggers on viewing and again when the victim reads it or sees the inbox preview.
5. For payloads with spaces/quotes, encode JS as char codes and eval: `<iframe src=javascript:eval(String.fromCharCode.apply(null,[...])) width=0 height=0 style=display:none;></iframe>`.
**How found:** Researcher noticed private messages render HTML and tested whether iframe javascript: URIs survive storage and execute on read/preview.
**Exploitation:** Attacker sends a crafted private message to a target; when the target opens the message or the inbox preview renders it, the iframe javascript: URI executes in the target's origin. The JS uses parent.jQuery.ajax to fetch wp-admin pages, fill form fields (e.g. field_1, blogname, role select) and POST serialized forms, performing any action the victim can: rename users, change site title/description, promote user id 2 to administrator, read emails, change passwords.
**Escalation:** Targeting an administrator yields full wp-admin access and plugin actions; payloads can be chained within one attack, and a worm could re-email itself to every user.
**Insight:** Inbox message-preview widgets that render stored HTML are a high-value XSS sink: test iframe src=javascript: and char-code eval encoding to bypass space/quote filtering, and target admin recipients for full site takeover.

