23

Recently I discovered how useful and easy parse.com is. It really speeds up the development and gives you an off-the-shelf database to store all the data coming from your web/mobile app.

But how secure is it? From what I understand, you have to embed your app private key in the code, thus granting access to the data.

But what if someone is able to recover the key from your app? I tried it myself. It took me 5 minutes to find the private key from a standard APK, and there is also the possibility to build a web app with the private key hard-coded in your javascript source where pretty much anyone can see it.

The only way to secure the data I've found are ACLs (https://www.parse.com/docs/data), but this still means that anyone may be able to tamper with writable data.

Can anyone enlighten me, please?

softice86
  • 233
  • 2
  • 5
  • This concerns me too. I found a couple links (https://parse.com/questions/prohibit-user-from-changing-their-own-game-score and https://parse.com/questions/javascript-sdk-security). I think Parse's ACL system probably is secure enough for the needs of my particular app, but I think for certain other uses, I'd need to learn more security practices to try to lock stuff down. – Ryan Feb 11 '13 at 18:50

4 Answers4

18

As with any backend server, you have to guard against potentially malicious clients. Parse has several levels of security to help you with that.

The first step is ACLs, as you said. You can also change permissions in the Data Browser to disable unauthorized clients from making new classes or adding rows or columns to existing classes.

If that level of security doesn't satisfy you, you can proxy your data access through Cloud Functions. This is like creating a virtual application server to provide a layer of access control between your clients and your backend data store.

bklimt
  • 1,822
  • 15
  • 11
  • 2
    It's definitely a different model than the ol' traditional, "here's a secret key you can hide in your server side code that lets you do anything," which doesn't work for JavaScript applications. The general idea that @bklimt covers here is, "Dear app user, you can't do anything until you log in, and once you log in Parse will restrict your activities based on the policy (ACLs and permissions) we have in place for your account." – Seth Dec 02 '14 at 22:47
  • 1
    This is why I love Cloud Function! You can filter all the requests, and do a lot more. – Jack Song Jun 03 '15 at 09:24
3

I've taken the following approach in the case where I just needed to expose a small view of the user data to a web app.

a. Create a secondary object which contains a subset of the secure objects fields.

b. Using ACLs, make the secure object only accessible from an appropriate login

c. Make the secondary object public read

d. Write a trigger to keep the secondary object synchronised with updates to the primary.

I also use cloud functions most of the time but this technique is useful when you need some flexibility and may be simpler than cloud functions if the secondary object is a view over multiple secure objects.

Rocket Garden
  • 1,166
  • 11
  • 26
0

What I did was the following.

  1. Restrict read/write for public for all classes. The only way to access the class data would be through the cloud code.
  2. Verify that the user is a logged in user using the parameter request.user ,and if the user session is null and if the object id is legit.
  3. When the user is verified then I would allow the data to be retrieved using the master key.
Edwin
  • 461
  • 1
  • 5
  • 14
0

Just keep a tight control on your Global Level Security options (client class creation, etc...), Class Level Security options (you can for instance, disable clients deleting _Installation entries. It's also common to disable user field creation for all classes.), and most important of all, look out for the ACLs.

Usually I use beforeSave triggers to make sure the ACLs are always correct. So, for instance, _User objects are where the recovery email is located. We don't want other users to be able to see each other's recovery emails, so all objects in the _User class must have read and write set to the user only (with public read false and public write false).

This way only the user itself can tamper with their own row. Other users won't even notice this row exists in your database.

One way to limit this further in some situations, is to use cloud functions. Let's say one user can send a message to another user. You may implement this as a new class Message, with the content of the message, and pointers to the user who sent the message and to the user who will receive the message.

Since the user who sent the message must be able to cancel it, and since the user who received the message must be able to receive it, both need to be able to read this row (so the ACL must have read permissions for both of them). However, we don't want either of them to tamper with the contents of the message.

So you have two alternatives: either you create a beforeSave trigger that checks if the modifications the users are trying to make to this row are valid before committing them, or you set the ACL of the message so that nobody has write permissions, and you create cloud functions that validates the user, and then modifies the message using the master key.

Point is, you have to make these considerations for every part of your application. As far as I know, there's no way around this.

brocoli
  • 542
  • 3
  • 16