# Any authenticated user can download full list of users, including email

Guardian check for CSV export compared entity type to nonexistent 'admin', so any authenticated user could export full user list including emails once per day.

- Payout: $256
- Severity: medium
- Program: Discourse
- Credited: arkadiyt
- Disclosed: 2017-06-17
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/228399
- Library page: https://bugbountylibrary.com/r/h1%3A228399
- Tags: domain:web impact:data-leak impact:pii-leak kind:bounty platform:hackerone sev:medium technique:source-review vuln:access-control vuln:info-disclosure

**Target:** ExportCsvController / CSV export endpoint
**Root cause:** Guardian#can_export_entity? only rejects entity type 'admin', which doesn't exist, so the check effectively only enforces a once-per-day rate limit rather than authorization.
**Steps:**
1. Authenticate as any regular user on a Discourse instance
2. Request CSV export for entity type `user_list` (and other types in ExportCsvFile job) via the export endpoint
3. Receive full user list CSV with names, emails, admin status
4. Repeat next day for another export
**How found:** Code reading of ExportCsvController and Guardian#can_export_entity?, noticing the check compares against a nonexistent 'admin' entity type, then testing on try.discourse.org.
**Exploitation:** Any authenticated user triggers the export endpoint for entity types like user_list; the guardian check passes because 'admin' is not a real entity type, yielding a CSV of all users including email addresses and staff actions.
**Insight:** When an authorization check compares against a string constant, verify that constant actually exists in the entity type enum — a typo'd or dead value silently disables the check.
