A Walk in the Workplace

This is part of a private bounty program organized by Facebook Bug Bounty Team.
Workplace is Facebook’s collaborative network for companies.
Contents
1. Disclosing Names of Workplace Users
2. See who created my Workplace
3. View the last active time for a separate Workplace instance
4. Determine the number of groups in a Workplace


Disclosing Names of Workplace Users

Using a help community profile, it is possible to disclose the name of a Workplace user from another Workplace instance. This is possible even when “Allow people to use the Help Community, which includes people who do not work for WorkPlaceName” is disabled in https://your-workplace-instance.facebook.com/work/admin/?section=settings
Proof of Concept
https://my-workplace-instance.facebook.com/help/work/community/profile/?uid=your-workplace-employee-id-1
https://my-workplace-instance.facebook.com/help/work/community/profile/?uid=your-workplace-employee-id-2
These two employees have never used the help community. So I would expect that if the option is disabled in the admin settings, these profiles shouldn’t be shown. In addition, it isn’t possible as far as I can tell to get this information another way.
* https://my-workplace-instance.facebook.com/your-workplace-employee-id-1
* https://graph.facebook.com/your-workplace-employee-id-1
* https://graph.facebook.com/graphql?q=node(your-workplace-employee-id-1)
Timeline

  • Dec 3, 2016 – Report Sent
  • Dec 5, 2016 – Escalation by Facebook
  • Dec 8, 2016 – Fixed by Facebook
  • Dec 15, 2016 – Bounty Awarded by Facebook

See who created my Workplace

The first notification seen when entering a Workplace, is that one is given the role of System Administrator. It’s possible to see who gave that role.
I thought about this feature as just being a part of just the white hat program given the familiarity of the name of the actor.
Proof of Concept
1. Get the community ID from the workplace at https://workplace-instance.facebook.com/work/admin/?section=settings
The community_id from a Graph API call shows that it’s of type Group. Since this isn’t really a group, let’s see what GraphQL presents us.
2. Execute a GraphQL call on the workplace-instance.facebook.com and query for Group Stories
curl 'https://workplace-instance.facebook.com/api/graphqlbatch/'
node(community_id){group_stories}
Response
{"q0":{"response":{"community_id":{"group_stories":{"nodes":[{"id":"story_id","url":"https:\/\/workplace-instance.facebook.com\/groups\/community_id\/permalink\/post_id\/","creation_time":1,"actors":[{"id":"employee_id","url":"https:\/\/workplace-instance.facebook.com\/employeeusername","name":"the employee"}],"message":null}]}}},"error":null}}
{
"successful_results": 1,
"error_results": 0,
"skipped_results": 0
}

This seems to represent an action taken by the employee right before I was given System Administrator access as shown by the following markup from the first notification jewel I see in Workplace,
<li class="_33c" data-gt="{"notif_type":"work_became_admin","alert_id":"1","unread":0,"from_uids":{"employee_id":employee_id},"microtime_sent":"1","content_id":"","row":3}" data-alert-id="1:1"><div class="anchorContainer"><div class=""><a href="https://workplace-instance.facebook.com/work/admin/?ref=notif&amp%3Bnotif_t=work_became_admin&amp%3Bnotif_id=1" class="_33e _1_0e"><div direction="left" class="clearfix"><div class="_ohe lfloat"><img src="https://www.facebook.com/images/icons-large/fb-wp-xl.png" alt="" class="_33h img _8o _8r img"></div><div class=""><div class="_42ef _8u"><div direction="right" class="clearfix"><div class="_ohf rfloat"><span></span></div><div class=""><div class="_42ef"><div class="_4l_v"><span><span>You were given the role of System Administrator.</span></span><div class="_33f clearfix" direction="left"><div class="_ohe lfloat"><img class="_10cu img _8o _8r img" src="https://static.xx.fbcdn.net/rsrc.php/v3/yr/r/fvUo2AfP2z4.png" alt=""></div><div class=""><div class="_42ef _8u"><span><abbr class="_33g livetimestamp" title="Thursday, 27 July 2017 at 00:01" data-utime="1">18 hours ago</abbr></span></div></div></div></div></div></div></div></div></div></div></a></div><div><span class=""><div aria-label="Read" class="_55ma _55m9 _5c9_" data-hover="tooltip" data-tooltip-alignh="center" data-tooltip-content="Read" tabindex="0"></div></span><span class=""><div data-testid="chevron" class="_1_0c _55m9 uiPopover _6a _6b"><a href="#" aria-label="Notification options" class="_1_0d _2agf _p" aria-haspopup="true" role="button"></a></div></span></div></div></li>
Specifically id (in GraphQL) and from_uids (notification jewel) show the employee_id. Since I assume that Workplace works in a similar fashion to Facebook, this should be possible,
https://workplace-instance.facebook.com/employee_id
Which resolves to https://workplace-instance.facebook.com/employeeusername (The public Facebook profile for the employee, not the Workplace profile)
as opposed to
https://workplace-instance.facebook.com/workplaceID (A Workplace User)
The ID from the GraphQL also represents the first story so the following works as well
Request
node(story_id){attachments,title,summary}
Response
{"story_id":{"attachments":[{"title_with_entities":{"text":"phwd"}}],"title":{"text":"Facebook Employee made phwd an admin of the group WorkplaceInstanceName."},"summary":{"text":"Facebook Employee made phwd an admin of the group WorkplaceInstanceName."}}

On the page https://workplace.fb.com/trust/, it’s stated that “We’ve designed the system so the information you share in one is not shared in the other.” So, in this scenario, if the person who created the Workplace instance is public, the actor ID should at least point to a Workplace Persona or be empty for regular users.
Timeline

  • Nov 21, 2016 – Report Sent
  • Nov 21, 2016 – Escalation by Facebook
  • Apr 21, 2017 – Fixed by Facebook
  • Apr 26, 2017 – Bounty Awarded by Facebook

View the last active time for a separate Workplace instance

Given access to any workplace instance, it is possible to see the last active time for a workplace (not joined). In a specific case, it means I know the activity timestamp for a second workplace instance using a user from a first workplace instance.
Instance to check: https://instance2.facebook.com/
Community ID for https://instance2.facebook.com/: workplaceCID2
User from https://instance1.facebook.com/
GraphQL query
curl 'https://instance1.facebook.com/api/graphqlbatch/'
node(workplaceCID2){last_activity_time}

Response
{"workplaceCID2":{"last_activity_time":1493044568}}}
This corresponds to the last group story in that community
Since I’m not able to get to workplaceCID2 via https://instance1.facebook.com/workplaceCID2 or login into https://instance2.facebook.com/ with user credentials from instance1 I’ll assume this activity date shouldn’t necessarily be shown.
Timeline

  • Nov 25, 2016 – Report Sent
  • Nov 25, 2016 – Escalation by Facebook
  • Jan 31, 2017 – Fixed by Facebook
  • Feb 1, 2017 – Bounty Awarded by Facebook

Determine the number of groups in a Workplace

I am to able know how many groups are in a Workplace that I’m not a member.
Proof of Concept
Query GraphQL for child groups count for the https://instance1.facebook.com/ instance as a Workplace User in the https://instance2.facebook.com/ instance
curl ‘https://instance2.facebook.com/api/graphqlbatch/’
node(instance1_ID){child_groups{count}}
Response
{"instance1_ID":{"child_groups":{"count":3}}
This represents the three groups in this Workplace https://instance1.facebook.com/
Generally, counts aren’t significant privacy issues.
Here is a detailed and reasonable explanation for this specific case
As you know, count privacy is a somewhat tricky issue within Facebook. There are many circumstances in which counts may be privacy-unaware (ie: tell you that someone has N albums when you can only see N-5), which is something we are working to change over time. In evaluating reports like this, the main question we ask ourselves is what the sensitivity of the information revealed is.
In this instance, the information itself (number of groups) is not particularly sensitive. The number of groups in a Workplace instance is independent of the number of employees (which some companies would consider sensitive) and can fluctuate very easily. However, when considering the issue in the context of Workplace, our assessment was that companies would find it unexpected for information about their usage of the site (like the number of groups) to be available to non-affiliated individuals. Given that, we ultimately concluded that this report should qualify under our program.
Timeline

  • Nov 30, 2016 – Report Sent
  • Dec 7, 2016 – Escalation by Facebook
  • Dec 29, 2016 – Bounty Awarded by Facebook