# Buddypress 2.9.1 - Exceeding the maximum upload size - XSS leading to potential RCE.

BuddyPress reflected the oversized-upload filename unsanitized in its error message, enabling XSS that an admin could chain to plugin-editor RCE.

- Payout: hidden
- Severity: medium
- Program: WordPress
- Found by: skansing
- Disclosed: 2017-11-02
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/263109
- Library page: https://bugbountylibrary.com/r/h1%3A263109
- Tags: area:web domain:web impact:integrity impact:rce kind:bounty platform:hackerone sev:medium tech:php tech:wordpress technique:chained vuln:rce vuln:xss

**Target:** BuddyPress avatar/cover-image upload error handler
**Root cause:** When an uploaded avatar or cover image exceeds the size limit, the error message echoes the attacker-controlled filename without HTML sanitization, allowing script injection.
**Steps:**
1. Log in as admin and go to `/wp-admin/users.php?page=bp-profile-edit`
2. Upload a file named `POC<img src=x onerror='document.write(atob("..."))'>` where the base64 decodes to a script tag loading an external RCE JS
3. The oversized-upload error renders the filename unsanitized, executing the onerror payload
4. Payload writes an iframe to `/wp-admin/plugin-editor.php?file=hello.php`, sets `#newcontent` to `<?php phpinfo();` and clicks `#submit`
5. Redirect to `/wp-content/plugins/hello.php` to trigger the modified plugin
**How found:** Noticed the upload-size error reflected the filename unsanitized, similar to a prior report (#203515), and built a chain to escalate from reflected XSS to RCE.
**Exploitation:** Social-engineer an admin into uploading a maliciously named oversized avatar/cover image; the reflected XSS runs same-origin, uses XSSI to bypass length limits, then drives the plugin editor to write PHP into hello.php and visit it for RCE.
**Escalation:** XSS chained to XSSI to bypass filename/char limits, then to plugin-editor abuse for code execution.
**Insight:** Upload error messages that echo the filename are a reliable XSS sink; when filename length limits block a full payload, use document.write(atob(...)) to load an external script and pivot to same-origin admin tools like the plugin editor.

