# [Buddypress] Arbitrary File Deletion through bp_avatar_set

BuddyPress avatar crop endpoint trusts the original_file parameter, letting any logged-in user path-traverse and unlink arbitrary web-server-deletable files like wp-config.php.

- Payout: hidden
- Severity: high
- Program: WordPress
- Found by: mopman
- Disclosed: 2017-08-22
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/183568
- Library page: https://bugbountylibrary.com/r/h1%3A183568
- Tags: area:web domain:web impact:dos impact:integrity kind:bounty platform:hackerone sev:high tech:php tech:wordpress technique:source-review vuln:file-upload vuln:path-traversal

**Target:** WordPress plugin avatar crop handler (bp_avatar_set action)
**Root cause:** The original_file parameter supplied during avatar cropping is passed to unlink() without validating that it resolves inside the user's avatar upload directory, so ../ sequences escape the uploads path.
**Steps:**
1. Register/log in as any user able to change their own avatar.
2. Go to /members/<username>/profile/change-avatar/ and upload a valid image; let the upload request complete.
3. Intercept the crop request and change original_file from the legitimate avatar URL to `http%3A%2F%2Flocalhost%2F~sam%2Fwordpress%2Fwp-content%2Fuploads%2Favatars%2F2%2F../../../../../wp-config.php` (add one extra ../ for the numbered folder).
4. Submit the request; unlink() deletes the targeted file, e.g. wp-config.php, taking the blog down.
**How found:** Researcher inspected the avatar crop flow, noticed original_file is attacker-controlled and used directly for deletion, and tested traversal by comparing the legitimate upload path to guess the folder depth.
**Exploitation:** Any authenticated low-privilege user intercepts the avatar crop POST and rewrites original_file with directory traversal to point at an arbitrary server-writable path; the server calls unlink() on it, deleting the file (wp-config.php shown, causing site outage).
**Insight:** Avatar/image crop handlers that accept a server-side file path for post-processing are prime unlink()/read sinks; always test the crop/rotate step separately from upload, since upload validation often doesn't cover the second request.

