📜 ⬆️ ⬇️

Parse security in iOS application



Parse is the most beautiful BaaS, allowing you to quickly raise a full-fledged server infrastructure for a mobile application. Perhaps it is because of this simplicity that many developers forget about emerging security issues and emerging vulnerabilities.

For those who are not familiar with the service, take a short excursion into what it is. Parse provides the developer with services such as cloud storage, push notifications, writing your own API, collecting statistics, crash logs, and more. In this study, we are interested in exactly the data warehouse, called Cloud Core.
All data in Parse is stored in classes (in fact - tables), between the records of which you can make full connections.


')
For each of the classes, client access rights are configured that affect the ability to search, add new entries, modify existing ones, and so on. By default, all actions are allowed. Of course, as usual, most developers, once setting up the tables they need, forget about setting up client permissions.



Closely confronted with Parse on one of the work projects and fiddling with the ACL setting, I decided to play around with other people's applications. I chose the object for research right at parse.com/customers . They became Cubefree - a search service for coworking sites.

To connect to the Parse account in the iOS application, a combination of two keys is used - Application ID and Client Key . To perform any actions on data in Cloud Core, the first thing you need to know this data. With the help of the smart idb utility, which automates many routine actions during pentesting, we will decipher the executable file of the application. While the process is underway, we ’ll check NSUserDefaults , the likely place to store the keys of interest.

In this case, everything is quite harmless - no confidential data. Let's go back to the decoded binary and feed it to Hopper disassembler , which specializes in reverse engineering of applications written in Objective-C. We’ll start searching for keys with the application: didFinishLaunchingWithOptions: method in AppDelegate . One of the great features of Hopper is the pseudo-code method representation, which significantly lowers the threshold for understanding decrypted code.



As expected, the connection to the Parse account is happening here. Using these keys, we will analyze the data structure of the application and access rights to them.

The next step is to find the names of the Parse tables. In fact, where to find them, it becomes clear from the same screenshot - immediately after connecting to the server, you should call the registerSubclass methods of several classes that inherit from the root PFObject . Each of them must necessarily implement the parseClassName method, which gives us the name of the table on the server.



Let us study the structure of each of the classes thus obtained:
PFQuery *query = [PFQuery queryWithClassName:@"ParseClassName"]; [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { NSLog(@"%@", objects); }]; 

However, knowledge of structure alone is not enough. To understand how we can affect the operation of the application, you need to determine the access rights to all Parse classes. This is done quite simply - we just execute requests to the server corresponding to various permissions and analyze their results. To simplify these routine actions, I wrote a simple Parse Revealer utility that automatically determines access levels to all known classes.

Based on our data, we can build a table:
Class nameData structureAccess rights
ChatRoomchatId (string)
user1 (User)
user2 (User)
GET: False
FIND: True
UPDATE: True
CREATE: True
DELETE: False
ADD FIELDS: True
CheckinavailableToShareTable (Bool)
date (Date)
invisible (Bool)
statusCheckin (String)
statusUser (String)
user (User)
workspace (Workspace)
GET: True
FIND: True
UPDATE: True
CREATE: True
DELETE: True
ADD FIELDS: True
ChatmessagechatId (string)
Message (String)
sender (User)
unread (Bool)
GET: False
FIND: True
UPDATE: True
CREATE: True
DELETE: False
ADD FIELDS: True
Notificationdate (Date)
sendUser (User)
chekin (cheking)
status (Bool)
type (Number)
accepted (Bool)
GET: True
FIND: True
UPDATE: True
CREATE: True
DELETE: False
ADD FIELDS: True
Reviewdate (Date)
parkingStatus (Number)
powerStatus (Number)
soundStatus (Number)
user (PFUser)
wifiStatus (Number)
workspace (Workspace)
GET: True
FIND: True
UPDATE: False
CREATE: True
DELETE: False
ADD FIELDS: True
Workspaceaddress (String)
cc (string)
city ​​(String)
country (String)
foursquareId (String)
lat (string)
lng (string)
location (PFGeoPoint)
name (String)
postalCode (String)
state (String)
GET: True
FIND: True
UPDATE: True
CREATE: True
DELETE: False
ADD FIELDS: True

As can be seen from the obtained access rights, the developers have implemented a certain security policy, but, all the same, insufficient. We show what results can be achieved by playing with the ChatMessage class.

The most obvious vulnerability - in any of the open chats, you can change both your own and other people's messages. After executing this code, a nice greeting turns into a habrasuicid:
 PFQuery *query = [PFQuery queryWithClassName:@"ChatMessage"]; [query whereKey:@"message" equalTo:@", !"]; [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { PFObject *object = [objects firstObject]; object[@"message"] = @",   !"; [object saveInBackground]; }]; 



Similarly, you can add new messages, you just need to provide the new PFObject with the correct chatId . But It is worth noting that Delete , set to false , will not allow us to delete any of the created objects.

A much more serious vulnerability is incorrect mapping of data obtained from Parse. If the newly created ChatMessage object has no sender field, the application crashes. Thus, nothing prevents us from running through all the watches ever created, adding an invalid message to them - and the application will crash for all users. This is already fraught with low ratings in the App Store, outflow of users and the failure of the project as a whole.
Other classes have similar vulnerabilities - but they are already beyond the scope of the current study.

As for security, everything is quite transparent here. Only a few rules need to be followed:

If you see the features of your applications in this study, you should not blame Parse - as I said before, this is an excellent service that minimizes the costs of creating the server part of the application. And all considered vulnerabilities are solely the responsibility of the developers of the application.

Useful links:

Other materials dedicated to the security of iOS applications:

Source: https://habr.com/ru/post/247541/


All Articles