In what way do you interact with private information of your users? I mean to information like their full name, email address, living address, phone number or any other kind of information that may be important to them, or information they’d rather keep private.
Today’s case-study talks just about that. Parental advisory: Parental advisory: Explicit content. Just kidding.
We will talk about the way private objects (and I’ll explain my interpretation of the term ‘objects’ later on) should be handled, and then we will see 2 neat examples from vulnerabilities I have found on Facebook (and were fixed, of course).
OK, so you’re mature enough to ask your users to trust you with their email address, home address and phone number. If you are smart, you’ll know that this type of information should be transmitted on the wire via HTTPS, but you’ll remember that sometimes it is also a good practice to encrypt it by yourself.
So your users info is properly transmitted and saved in the database, you assume that your DB is immune to SQL injections or other leakage incidents, and you are thinking of cracking a beer and starting another episode of How I Met Your Mother.
Awesome! But first, I’d like to introduce you to another enemy: The IDOR.
Insecure Direct Object References are your information’s second-worst enemy (after SQLi, of course). Attacker who is able to access other users private objects (such as email address, phone number, etc) could basically expose all of the private data from the server, without “talking” with the DB directly or run arbitrary code on the server.
This is the time to explain my definition to “private objects”. User objects are not just the user’s phone number, email address, name, gender, sexual-orientation or favorite side of the bed. They are also objects that the user creates or own, like the items in the user’s cart, a group that the user is managing or a paint that a user has drew.
The best way to handle private objects is to define them as private and treat them with the appropriate honor.
If you know that only a certain user (or users) should be able to access a certain object, make sure that only those users IDs (or other unique-identifier) are able to access and mess with that object.
How will you do so?
Using a Private Object Manager (POM) of course.
The idea is simple: A one-and-only mechanism that will fetch or change information about private objects only if an accepted identifier has been provided.
For example: A class that will return the email address of the user ID ‘212’ only if the ID of the user who requested that information is ‘212’).
Sounds obvious, right?
Before posting this case-study I had a little chat with some colleague about the idea of creating a unique mechanism that will handle all the requests to private objects.
He said that this is useless
“Because when a request is being made regarding a certain object, it is the job of the session manager to make sure that the currently active session is messing around with an object it has access to.”
But he was wrong. Very wrong.
Everyone knows Facebook events and groups. Everyone is part of a certain group on Facebook, or got an invitation to a certain event.
Like any other feature of Facebook (and especially after Cambridge Analytica data scandal), groups and events has different privacy levels. They can be public — and then every use will be able to see the event/group name and entire content, private — and then every user will be able to see the event/group name but not their content or secret— and then only users who were invited to join the group or participate an event will be able to see their name and content. Regular Facebook search does not discovers the existence of such groups/events.
Almost every object on Facebook has an ID — usually a long number that represents that object in Facebook’s huge Database, and so do groups and events.
So How can one determine the name or the content of a secret group or event?
I’ve spent a lot of time on the modern Facebook platform trying to fetch information from secret groups and events I cannot actually see, only by their ID.
But I couldn’t find any lead to disclose private information from secret objects. On Facebook’s modern platform. Modern.
And that’s when I started to think
Facebook has many versions to its web platform (and even to its mobile one).
Do they use the same Private Object Manager to access “sensitive” objects like a secret group or event?
Immediately after I’ve started to test the mbasic version of Facebook, I realized that things there work a little different. Ok, a lot different.
I have found 2 vulnerabilities which allowed the name of a secret group or event to be disclosed to any user, regardless the fact that he is not invited or in the group/event. The first vulnerability is here by presented, but the second one is yet to be fully patched (in progress these days):
Always wear a condom
Seriously, these vulnerabilities would have been prevented if Facebook would have implemented a single Private Object Manager to any of its version.
The idea of hoping that a session manager will prevent an insecure access to an object is ridiculous, simply because some objects are so wildly used (like groups on Facebook with millions of members), that the linkage of a user session to that object is high inefficient (and wrong).
Having a one and only filtering mechanism, a condom, to access the most important objects or details, is considered a best practice.