# Unauthenticated hidden groups disclosure via Ajax groups search

Unauthenticated users can disclose hidden BuddyPress groups' titles, descriptions, avatars and member counts by injecting show_hidden=1 via the Ajax groups filter cookie parameter.

- Payout: hidden
- Severity: medium
- Program: WordPress
- Found by: jdgrimes
- Disclosed: 2017-11-02
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/282176
- Library page: https://bugbountylibrary.com/r/h1%3A282176
- Tags: area:web domain:web impact:data-leak kind:bounty platform:hackerone sev:medium tech:php tech:wordpress technique:param-pollution technique:source-review vuln:access-control vuln:info-disclosure

**Target:** WordPress plugin BuddyPress Ajax groups_filter handler (admin-ajax.php)
**Root cause:** bp_legacy_theme_ajax_querystring() concatenates the bp-$object-filter and bp-$object-scope cookie values into the query string without urlencode(), so an attacker-supplied cookie value can inject extra query args like show_hidden=1 into BP_Groups_Template.
**Steps:**
1. Identify that groups-loop.php calls `bp_has_groups( bp_ajax_querystring( 'groups' ) )`.
2. Note bp_legacy_theme_ajax_querystring() builds `$qs[] = 'type=' . $_BP_COOKIE['bp-groups-filter']` without urlencode.
3. Note $_BP_COOKIE is populated from `$_POST['cookie']` via wp_parse_args after urldecode.
4. Send POST to `/wp-admin/admin-ajax.php` with body `action=groups_filter&cookie=bp-groups-filter%253D%252526show_hidden%3D1&object=groups`.
5. Observe hidden groups returned in the response; alternatively use `cookie=bp-groups-scope%253D%252526show_hidden%3D1`.
6. Same vector exists in bp_dtheme_ajax_querystring() via unencoded `$_POST['search_terms']`.
**How found:** Code review of BP_Groups_Group::get() showed show_hidden/status args are unrestricted; traced callers to bp_has_groups() and found the Ajax querystring builder concatenates cookie values without urlencode, enabling arg injection.
**Exploitation:** Unauthenticated attacker posts a crafted cookie parameter to admin-ajax.php groups_filter action; the decoded value injects `&show_hidden=1` into the groups query string, causing BP_Groups_Template to set show_hidden=true and return hidden groups' metadata (title, description, avatar, last activity, member count).
**Insight:** When a query builder concatenates cookie-derived values into a query string, look for missing urlencode() to inject extra query args (like show_hidden) that the template class only conditionally sets.

